diff --git a/crates/amalthea/src/fixtures/dummy_frontend.rs b/crates/amalthea/src/fixtures/dummy_frontend.rs index d239bf67e..33c1a1e52 100644 --- a/crates/amalthea/src/fixtures/dummy_frontend.rs +++ b/crates/amalthea/src/fixtures/dummy_frontend.rs @@ -7,13 +7,11 @@ use assert_matches::assert_matches; use rand::Rng; -use serde_json::Value; use crate::connection_file::ConnectionFile; use crate::registration_file::RegistrationFile; use crate::session::Session; use crate::socket::socket::Socket; -use crate::wire::execute_input::ExecuteInput; use crate::wire::execute_request::ExecuteRequest; use crate::wire::handshake_reply::HandshakeReply; use crate::wire::input_reply::InputReply; @@ -22,7 +20,6 @@ use crate::wire::jupyter_message::Message; use crate::wire::jupyter_message::ProtocolMessage; use crate::wire::jupyter_message::Status; use crate::wire::status::ExecutionState; -use crate::wire::stream::Stream; use crate::wire::wire_message::WireMessage; pub struct DummyConnection { @@ -268,206 +265,264 @@ impl DummyFrontend { Self::recv(&self.stdin_socket) } - /// Receive from Shell and assert `ExecuteReply` message. - /// Returns `execution_count`. - pub fn recv_shell_execute_reply(&self) -> u32 { - let msg = self.recv_shell(); - - assert_matches!(msg, Message::ExecuteReply(data) => { - assert_eq!(data.content.status, Status::Ok); - data.content.execution_count - }) + /// Send back an `InputReply` to an `InputRequest` over Stdin + pub fn send_stdin_input_reply(&self, value: String) { + self.send_stdin(InputReply { value }) } - /// Receive from Shell and assert `ExecuteReplyException` message. - /// Returns `execution_count`. - pub fn recv_shell_execute_reply_exception(&self) -> u32 { - let msg = self.recv_shell(); + /// Receives a (raw) message from the heartbeat socket + pub fn recv_heartbeat(&self) -> zmq::Message { + let mut msg = zmq::Message::new(); + self.heartbeat_socket.recv(&mut msg).unwrap(); + msg + } - assert_matches!(msg, Message::ExecuteReplyException(data) => { - assert_eq!(data.content.status, Status::Error); - data.content.execution_count - }) + /// Sends a (raw) message to the heartbeat socket + pub fn send_heartbeat(&self, msg: zmq::Message) { + self.heartbeat_socket.send(msg).unwrap(); } +} - /// Receive from IOPub and assert Busy message - pub fn recv_iopub_busy(&self) -> () { - let msg = self.recv_iopub(); +impl DummyFrontend { + pub fn flush_incoming(name: &str, socket: &Socket) { + eprintln!("{name} has incoming data:"); - assert_matches!(msg, Message::Status(data) => { - assert_eq!(data.content.execution_state, ExecutionState::Busy); - }); + while socket.has_incoming_data().unwrap() { + dbg!(WireMessage::read_from_socket(socket).unwrap()); + eprintln!("---"); + } + } +} + +impl Default for ExecuteRequestOptions { + fn default() -> Self { + Self { allow_stdin: false } } +} + +/// Receive from Shell and assert `ExecuteReply` message. +/// Returns `execution_count`. +#[macro_export] +macro_rules! recv_shell_execute_reply { + ($frontend:expr) => {{ + let msg = $frontend.recv_shell(); + + ::assert_matches::assert_matches!(msg, $crate::wire::jupyter_message::Message::ExecuteReply(data) => { + assert_eq!(data.content.status, $crate::wire::jupyter_message::Status::Ok); + data.content.execution_count + }) + }}; +} - /// Receive from IOPub and assert Idle message - pub fn recv_iopub_idle(&self) -> () { - let msg = self.recv_iopub(); +/// Receive from Shell and assert `ExecuteReplyException` message. +/// Returns `execution_count`. +#[macro_export] +macro_rules! recv_shell_execute_reply_exception { + ($frontend:expr) => {{ + let msg = $frontend.recv_shell(); + ::assert_matches::assert_matches!(msg, $crate::wire::jupyter_message::Message::ExecuteReplyException(data) => { + assert_eq!(data.content.status, $crate::wire::jupyter_message::Status::Error); + data.content.execution_count + }) + }}; +} - assert_matches!(msg, Message::Status(data) => { - assert_eq!(data.content.execution_state, ExecutionState::Idle); +/// Receive from IOPub and assert Busy message. +#[macro_export] +macro_rules! recv_iopub_busy { + ($frontend:expr) => {{ + let msg = $frontend.recv_iopub(); + ::assert_matches::assert_matches!(msg, $crate::wire::jupyter_message::Message::Status(data) => { + assert_eq!(data.content.execution_state, $crate::wire::status::ExecutionState::Busy); }); - } + }}; +} - /// Receive from IOPub and assert ExecuteInput message - pub fn recv_iopub_execute_input(&self) -> ExecuteInput { - let msg = self.recv_iopub(); +/// Receive from IOPub and assert Idle message. +#[macro_export] +macro_rules! recv_iopub_idle { + ($frontend:expr) => {{ + let msg = $frontend.recv_iopub(); + ::assert_matches::assert_matches!(msg, $crate::wire::jupyter_message::Message::Status(data) => { + assert_eq!(data.content.execution_state, $crate::wire::status::ExecutionState::Idle); + }); + }}; +} - assert_matches!(msg, Message::ExecuteInput(data) => { +/// Receive from IOPub and assert ExecuteInput message. +#[macro_export] +macro_rules! recv_iopub_execute_input { + ($frontend:expr) => {{ + let msg = $frontend.recv_iopub(); + ::assert_matches::assert_matches!(msg, $crate::wire::jupyter_message::Message::ExecuteInput(data) => { data.content }) - } - - /// Receive from IOPub and assert ExecuteResult message. Returns compulsory - /// `plain/text` result. - pub fn recv_iopub_execute_result(&self) -> String { - let msg = self.recv_iopub(); + }}; +} - assert_matches!(msg, Message::ExecuteResult(data) => { - assert_matches!(data.content.data, Value::Object(map) => { - assert_matches!(map["text/plain"], Value::String(ref string) => { +/// Receive from IOPub and assert ExecuteResult message. Returns compulsory `plain/text` result. +#[macro_export] +macro_rules! recv_iopub_execute_result { + ($frontend:expr) => {{ + let msg = $frontend.recv_iopub(); + ::assert_matches::assert_matches!(msg, $crate::wire::jupyter_message::Message::ExecuteResult(data) => { + ::assert_matches::assert_matches!(data.content.data, serde_json::Value::Object(map) => { + ::assert_matches::assert_matches!(map["text/plain"], serde_json::Value::String(ref string) => { string.clone() }) }) }) - } - - pub fn recv_iopub_display_data(&self) { - let msg = self.recv_iopub(); - assert_matches!(msg, Message::DisplayData(_)) - } + }}; +} - pub fn recv_iopub_update_display_data(&self) { - let msg = self.recv_iopub(); - assert_matches!(msg, Message::UpdateDisplayData(_)) - } +/// Receive from IOPub and assert DisplayData message. +#[macro_export] +macro_rules! recv_iopub_display_data { + ($frontend:expr) => {{ + let msg = $frontend.recv_iopub(); + ::assert_matches::assert_matches!( + msg, + $crate::wire::jupyter_message::Message::DisplayData(_) + ) + }}; +} - pub fn recv_iopub_stream_stdout(&self, expect: &str) { - self.recv_iopub_stream(expect, Stream::Stdout) - } +/// Receive from IOPub and assert UpdateDisplayData message. +#[macro_export] +macro_rules! recv_iopub_update_display_data { + ($frontend:expr) => {{ + let msg = $frontend.recv_iopub(); + ::assert_matches::assert_matches!( + msg, + $crate::wire::jupyter_message::Message::UpdateDisplayData(_) + ) + }}; +} - pub fn recv_iopub_stream_stderr(&self, expect: &str) { - self.recv_iopub_stream(expect, Stream::Stderr) - } +/// Receive from IOPub and assert CommClose message. Returns comm_id. +#[macro_export] +macro_rules! recv_iopub_comm_close { + ($frontend:expr) => {{ + let msg = $frontend.recv_iopub(); + ::assert_matches::assert_matches!(msg, $crate::wire::jupyter_message::Message::CommClose(data) => { + data.content.comm_id + }) + }}; +} - pub fn recv_iopub_comm_close(&self) -> String { - let msg = self.recv_iopub(); +/// Receive from IOPub and assert ExecuteError message. Returns `evalue`. +#[macro_export] +macro_rules! recv_iopub_execute_error { + ($frontend:expr) => {{ + let msg = $frontend.recv_iopub(); + ::assert_matches::assert_matches!(msg, $crate::wire::jupyter_message::Message::ExecuteError(data) => { + data.content.exception.evalue + }) + }}; +} - assert_matches!(msg, Message::CommClose(data) => { - data.content.comm_id +/// Receive from Stdin and assert InputRequest message. Returns the prompt. +#[macro_export] +macro_rules! recv_stdin_input_request { + ($frontend:expr) => {{ + let msg = $frontend.recv_stdin(); + ::assert_matches::assert_matches!(msg, $crate::wire::jupyter_message::Message::InputRequest(data) => { + data.content.prompt }) - } + }}; +} - /// Receive from IOPub Stream - /// - /// Stdout and Stderr Stream messages are buffered, so to reliably test against them - /// we have to collect the messages in batches on the receiving end and compare against - /// an expected message. - fn recv_iopub_stream(&self, expect: &str, stream: Stream) { +/// Receive from IOPub Stream +/// +/// Stdout and Stderr Stream messages are buffered, so to reliably test against them +/// we have to collect the messages in batches on the receiving end and compare against +/// an expected message. +#[macro_export] +macro_rules! recv_iopub_stream { + ($frontend:expr, $expect:expr, $stream:expr) => {{ let mut out = String::new(); loop { // Receive a piece of stream output (with a timeout) - let msg = self.recv_iopub(); + let msg = $frontend.recv_iopub(); // Assert its type - let piece = assert_matches!(msg, Message::Stream(data) => { - assert_eq!(data.content.name, stream); + let piece = ::assert_matches::assert_matches!(msg, $crate::wire::jupyter_message::Message::Stream(data) => { + assert_eq!(data.content.name, $stream); data.content.text }); // Add to what we've already collected out += piece.as_str(); - if out == expect { + if out == $expect { // Done, found the entire `expect` string - return; + break; } - if !expect.starts_with(out.as_str()) { + if !$expect.starts_with(out.as_str()) { // Something is wrong, message doesn't match up - panic!("Expected IOPub stream of '{expect}'. Actual stream of '{out}'."); + panic!("Expected IOPub stream of '{expect}'. Actual stream of '{out}'.", expect = $expect, out = out); } // We have a prefix of `expect`, but not the whole message yet. // Wait on the next IOPub Stream message. } - } - - /// Receive from IOPub and assert ExecuteResult message. Returns compulsory - /// `evalue` field. - pub fn recv_iopub_execute_error(&self) -> String { - let msg = self.recv_iopub(); - - assert_matches!(msg, Message::ExecuteError(data) => { - data.content.exception.evalue - }) - } - - /// Receive from Stdin and assert `InputRequest` message. - /// Returns the `prompt`. - pub fn recv_stdin_input_request(&self) -> String { - let msg = self.recv_stdin(); - - assert_matches!(msg, Message::InputRequest(data) => { - data.content.prompt - }) - } - - /// Send back an `InputReply` to an `InputRequest` over Stdin - pub fn send_stdin_input_reply(&self, value: String) { - self.send_stdin(InputReply { value }) - } + }}; +} - /// Receives a (raw) message from the heartbeat socket - pub fn recv_heartbeat(&self) -> zmq::Message { - let mut msg = zmq::Message::new(); - self.heartbeat_socket.recv(&mut msg).unwrap(); - msg - } +/// Receive from IOPub and assert Stdout Stream message. +#[macro_export] +macro_rules! recv_iopub_stream_stdout { + ($frontend:expr, $expect:expr) => {{ + $crate::recv_iopub_stream!($frontend, $expect, $crate::wire::stream::Stream::Stdout) + }}; +} - /// Sends a (raw) message to the heartbeat socket - pub fn send_heartbeat(&self, msg: zmq::Message) { - self.heartbeat_socket.send(msg).unwrap(); - } +/// Receive from IOPub and assert Stderr Stream message. +#[macro_export] +macro_rules! recv_iopub_stream_stderr { + ($frontend:expr, $expect:expr) => {{ + $crate::recv_iopub_stream!($frontend, $expect, $crate::wire::stream::Stream::Stderr) + }}; +} - /// Asserts that no socket has incoming data - pub fn assert_no_incoming(&mut self) { +#[macro_export] +macro_rules! assert_no_incoming { + ($frontend:expr) => {{ let mut has_incoming = false; - if self.iopub_socket.has_incoming_data().unwrap() { + if $frontend.iopub_socket.has_incoming_data().unwrap() { has_incoming = true; - Self::flush_incoming("IOPub", &self.iopub_socket); + $crate::fixtures::dummy_frontend::DummyFrontend::flush_incoming( + "IOPub", + &$frontend.iopub_socket, + ); } - if self.shell_socket.has_incoming_data().unwrap() { + if $frontend.shell_socket.has_incoming_data().unwrap() { has_incoming = true; - Self::flush_incoming("Shell", &self.shell_socket); + $crate::fixtures::dummy_frontend::DummyFrontend::flush_incoming( + "Shell", + &$frontend.shell_socket, + ); } - if self.stdin_socket.has_incoming_data().unwrap() { + if $frontend.stdin_socket.has_incoming_data().unwrap() { has_incoming = true; - Self::flush_incoming("StdIn", &self.stdin_socket); + $crate::fixtures::dummy_frontend::DummyFrontend::flush_incoming( + "StdIn", + &$frontend.stdin_socket, + ); } - if self.heartbeat_socket.has_incoming_data().unwrap() { + if $frontend.heartbeat_socket.has_incoming_data().unwrap() { has_incoming = true; - Self::flush_incoming("Heartbeat", &self.heartbeat_socket); + $crate::fixtures::dummy_frontend::DummyFrontend::flush_incoming( + "Heartbeat", + &$frontend.heartbeat_socket, + ); } if has_incoming { panic!("Sockets must be empty on exit (see details above)"); } - } - - fn flush_incoming(name: &str, socket: &Socket) { - eprintln!("{name} has incoming data:"); - - while socket.has_incoming_data().unwrap() { - dbg!(WireMessage::read_from_socket(socket).unwrap()); - eprintln!("---"); - } - } -} - -impl Default for ExecuteRequestOptions { - fn default() -> Self { - Self { allow_stdin: false } - } + }}; } diff --git a/crates/amalthea/tests/client.rs b/crates/amalthea/tests/client.rs index e20f27fdb..ce6663bf9 100644 --- a/crates/amalthea/tests/client.rs +++ b/crates/amalthea/tests/client.rs @@ -9,8 +9,17 @@ mod control; mod dummy_frontend; mod shell; +use amalthea::assert_no_incoming; use amalthea::comm::comm_channel::CommMsg; use amalthea::comm::event::CommManagerEvent; +use amalthea::recv_iopub_busy; +use amalthea::recv_iopub_comm_close; +use amalthea::recv_iopub_execute_input; +use amalthea::recv_iopub_execute_result; +use amalthea::recv_iopub_idle; +use amalthea::recv_iopub_stream_stdout; +use amalthea::recv_shell_execute_reply; +use amalthea::recv_stdin_input_request; use amalthea::socket::comm::CommInitiator; use amalthea::socket::comm::CommSocket; use amalthea::wire::comm_close::CommClose; @@ -32,7 +41,7 @@ fn test_amalthea_kernel_info() { // Ask the kernel for the kernel info. This should return an object with the // language "Test" defined in our shell handler. frontend.send_shell(KernelInfoRequest {}); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); assert_matches!( frontend.recv_shell(), @@ -43,7 +52,7 @@ fn test_amalthea_kernel_info() { } ); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); } #[test] @@ -52,15 +61,15 @@ fn test_amalthea_execute_request() { let code = "42"; frontend.send_execute_request(code, Default::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert_eq!(frontend.recv_iopub_execute_result(), "42"); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_iopub_execute_result!(frontend), "42"); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); } #[test] @@ -69,22 +78,22 @@ fn test_amalthea_input_request() { let code = "prompt"; frontend.send_execute_request(code, Default::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - let prompt = frontend.recv_stdin_input_request(); + let prompt = recv_stdin_input_request!(frontend); assert_eq!(prompt, "Amalthea Echo> "); frontend.send_stdin_input_reply(String::from("42")); - frontend.recv_iopub_stream_stdout("42"); - assert_eq!(frontend.recv_iopub_execute_result(), "prompt"); + recv_iopub_stream_stdout!(frontend, "42"); + assert_eq!(recv_iopub_execute_result!(frontend), "prompt"); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); } #[test] @@ -97,7 +106,7 @@ fn test_amalthea_heartbeat() { #[test] fn test_amalthea_comms() { - let mut frontend = DummyAmaltheaFrontend::lock(); + let frontend = DummyAmaltheaFrontend::lock(); let comm_id = "A3A6D0EA-1443-4F70-B059-F423E445B8D6"; @@ -107,9 +116,9 @@ fn test_amalthea_comms() { data: serde_json::Value::Null, }); - frontend.recv_iopub_busy(); - assert_eq!(frontend.recv_iopub_comm_close(), comm_id.to_string()); - frontend.recv_iopub_idle(); + recv_iopub_busy!(frontend); + assert_eq!(recv_iopub_comm_close!(frontend), comm_id.to_string()); + recv_iopub_idle!(frontend); frontend.send_shell(CommOpen { comm_id: comm_id.to_string(), @@ -119,14 +128,14 @@ fn test_amalthea_comms() { // Absorb the IOPub messages that the kernel sends back during the // processing of the above `CommOpen` request - frontend.recv_iopub_busy(); - frontend.recv_iopub_idle(); - frontend.assert_no_incoming(); + recv_iopub_busy!(frontend); + recv_iopub_idle!(frontend); + assert_no_incoming!(frontend); frontend.send_shell(CommInfoRequest { target_name: "".to_string(), }); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); assert_matches!(frontend.recv_shell(), Message::CommInfoReply(request) => { // Ensure the comm we just opened is in the list of comms @@ -134,8 +143,8 @@ fn test_amalthea_comms() { assert!(comms.contains_key(comm_id)); }); - frontend.recv_iopub_idle(); - frontend.assert_no_incoming(); + recv_iopub_idle!(frontend); + assert_no_incoming!(frontend); // Test requesting comm info and filtering by target name. We should get // back an empty list of comms, since we haven't opened any comms with @@ -143,15 +152,15 @@ fn test_amalthea_comms() { frontend.send_shell(CommInfoRequest { target_name: "i-think-not".to_string(), }); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); assert_matches!(frontend.recv_shell(), Message::CommInfoReply(request) => { let comms = request.content.comms; assert!(comms.is_empty()); }); - frontend.recv_iopub_idle(); - frontend.assert_no_incoming(); + recv_iopub_idle!(frontend); + assert_no_incoming!(frontend); let comm_req_id = frontend.send_shell(CommWireMsg { comm_id: comm_id.to_string(), @@ -159,7 +168,7 @@ fn test_amalthea_comms() { data: serde_json::json!({ "id": "foo" }), }); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); let mut got_idle = false; let mut got_reply = false; @@ -205,15 +214,15 @@ fn test_amalthea_comms() { comm_id: comm_id.to_string(), }); - frontend.recv_iopub_busy(); - frontend.recv_iopub_idle(); + recv_iopub_busy!(frontend); + recv_iopub_idle!(frontend); // Test to see if the comm is still in the list of comms after closing it // (it should not be) frontend.send_shell(CommInfoRequest { target_name: "variables".to_string(), }); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); assert_matches!(frontend.recv_shell(), Message::CommInfoReply(request) => { // Ensure the comm we just closed not present in the list of comms @@ -221,7 +230,7 @@ fn test_amalthea_comms() { assert!(!comms.contains_key(comm_id)); }); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); } #[test] @@ -262,7 +271,7 @@ fn test_amalthea_comm_open_from_kernel() { target_name: test_comm_name.clone(), }); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); assert_matches!(frontend.recv_shell(), Message::CommInfoReply(request) => { // Ensure the comm we just opened is in the list of comms @@ -275,7 +284,7 @@ fn test_amalthea_comm_open_from_kernel() { assert!(target.target_name == test_comm_name) }); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); // Now send a message from the backend to the frontend using the comm we just // created. diff --git a/crates/amalthea/tests/dummy_frontend/mod.rs b/crates/amalthea/tests/dummy_frontend/mod.rs index f5985ee8e..3c6165e99 100644 --- a/crates/amalthea/tests/dummy_frontend/mod.rs +++ b/crates/amalthea/tests/dummy_frontend/mod.rs @@ -13,6 +13,7 @@ use std::sync::Mutex; use std::sync::MutexGuard; use std::sync::OnceLock; +use amalthea::assert_no_incoming; use amalthea::comm::event::CommManagerEvent; use amalthea::fixtures::dummy_frontend::DummyConnection; use amalthea::fixtures::dummy_frontend::DummyFrontend; @@ -106,7 +107,7 @@ impl DummyAmaltheaFrontend { // Check that we haven't left crumbs behind impl Drop for DummyAmaltheaFrontend { fn drop(&mut self) { - self.assert_no_incoming() + assert_no_incoming!(self) } } diff --git a/crates/ark/src/fixtures/dummy_frontend.rs b/crates/ark/src/fixtures/dummy_frontend.rs index 5823dd16c..891d4e086 100644 --- a/crates/ark/src/fixtures/dummy_frontend.rs +++ b/crates/ark/src/fixtures/dummy_frontend.rs @@ -5,6 +5,7 @@ use std::sync::Mutex; use std::sync::MutexGuard; use std::sync::OnceLock; +use amalthea::assert_no_incoming; use amalthea::fixtures::dummy_frontend::DummyConnection; use amalthea::fixtures::dummy_frontend::DummyFrontend; @@ -125,7 +126,7 @@ impl DummyArkFrontend { // Check that we haven't left crumbs behind impl Drop for DummyArkFrontend { fn drop(&mut self) { - self.assert_no_incoming() + assert_no_incoming!(self); } } diff --git a/crates/ark/tests/kernel-notebook.rs b/crates/ark/tests/kernel-notebook.rs index 9051111f2..a18fb14ab 100644 --- a/crates/ark/tests/kernel-notebook.rs +++ b/crates/ark/tests/kernel-notebook.rs @@ -1,4 +1,13 @@ use amalthea::fixtures::dummy_frontend::ExecuteRequestOptions; +use amalthea::recv_iopub_busy; +use amalthea::recv_iopub_execute_error; +use amalthea::recv_iopub_execute_input; +use amalthea::recv_iopub_execute_result; +use amalthea::recv_iopub_idle; +use amalthea::recv_iopub_stream_stdout; +use amalthea::recv_shell_execute_reply; +use amalthea::recv_shell_execute_reply_exception; +use amalthea::recv_stdin_input_request; use ark::fixtures::DummyArkFrontendNotebook; #[test] @@ -6,15 +15,15 @@ fn test_notebook_execute_request() { let frontend = DummyArkFrontendNotebook::lock(); frontend.send_execute_request("42", ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, "42"); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] 42"); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] 42"); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -22,17 +31,17 @@ fn test_execute_request_error_multiple_expressions() { let frontend = DummyArkFrontendNotebook::lock(); frontend.send_execute_request("1\nstop('foobar')\n2", ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, "1\nstop('foobar')\n2"); - assert!(frontend.recv_iopub_execute_error().contains("foobar")); + assert!(recv_iopub_execute_error!(frontend).contains("foobar")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); assert_eq!( - frontend.recv_shell_execute_reply_exception(), + recv_shell_execute_reply_exception!(frontend), input.execution_count ); } @@ -43,20 +52,20 @@ fn test_notebook_execute_request_multiple_expressions() { let code = "1\nprint(2)\n3"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); // Printed output - frontend.recv_iopub_stream_stdout("[1] 2\n"); + recv_iopub_stream_stdout!(frontend, "[1] 2\n"); // Unlike console mode, we don't get intermediate results in notebooks - assert_eq!(frontend.recv_iopub_execute_result(), "[1] 3"); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] 3"); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -65,19 +74,17 @@ fn test_notebook_execute_request_incomplete() { let code = "1 +"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert!(frontend - .recv_iopub_execute_error() - .contains("Can't execute incomplete input")); + assert!(recv_iopub_execute_error!(frontend).contains("Can't execute incomplete input")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); assert_eq!( - frontend.recv_shell_execute_reply_exception(), + recv_shell_execute_reply_exception!(frontend), input.execution_count ) } @@ -88,19 +95,17 @@ fn test_notebook_execute_request_incomplete_multiple_lines() { let code = "1 +\n2 +"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert!(frontend - .recv_iopub_execute_error() - .contains("Can't execute incomplete input")); + assert!(recv_iopub_execute_error!(frontend).contains("Can't execute incomplete input")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); assert_eq!( - frontend.recv_shell_execute_reply_exception(), + recv_shell_execute_reply_exception!(frontend), input.execution_count ) } @@ -113,21 +118,21 @@ fn test_notebook_stdin_basic_prompt() { let code = "readline('prompt>')"; frontend.send_execute_request(code, options); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - let prompt = frontend.recv_stdin_input_request(); + let prompt = recv_stdin_input_request!(frontend); assert_eq!(prompt, String::from("prompt>")); frontend.send_stdin_input_reply(String::from("hi")); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] \"hi\""); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] \"hi\""); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -138,21 +143,21 @@ fn test_notebook_stdin_followed_by_an_expression_on_the_same_line() { let code = "val <- readline('prompt>'); paste0(val,'-there')"; frontend.send_execute_request(code, options); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - let prompt = frontend.recv_stdin_input_request(); + let prompt = recv_stdin_input_request!(frontend); assert_eq!(prompt, String::from("prompt>")); frontend.send_stdin_input_reply(String::from("hi")); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] \"hi-there\""); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] \"hi-there\""); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -164,19 +169,19 @@ fn test_notebook_stdin_followed_by_an_expression_on_the_next_line() { // Note, `1` is an intermediate output and is not emitted in notebooks let code = "1\nval <- readline('prompt>')\npaste0(val,'-there')"; frontend.send_execute_request(code, options); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - let prompt = frontend.recv_stdin_input_request(); + let prompt = recv_stdin_input_request!(frontend); assert_eq!(prompt, String::from("prompt>")); frontend.send_stdin_input_reply(String::from("hi")); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] \"hi-there\""); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] \"hi-there\""); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } diff --git a/crates/ark/tests/kernel.rs b/crates/ark/tests/kernel.rs index 042142cec..f98f5d0f6 100644 --- a/crates/ark/tests/kernel.rs +++ b/crates/ark/tests/kernel.rs @@ -1,4 +1,14 @@ use amalthea::fixtures::dummy_frontend::ExecuteRequestOptions; +use amalthea::recv_iopub_busy; +use amalthea::recv_iopub_execute_error; +use amalthea::recv_iopub_execute_input; +use amalthea::recv_iopub_execute_result; +use amalthea::recv_iopub_idle; +use amalthea::recv_iopub_stream_stderr; +use amalthea::recv_iopub_stream_stdout; +use amalthea::recv_shell_execute_reply; +use amalthea::recv_shell_execute_reply_exception; +use amalthea::recv_stdin_input_request; use amalthea::wire::jupyter_message::Message; use amalthea::wire::kernel_info_request::KernelInfoRequest; use ark::fixtures::DummyArkFrontend; @@ -17,8 +27,8 @@ fn test_kernel_info() { assert_eq!(reply.content.language_info.nbconvert_exporter, None); }); - frontend.recv_iopub_busy(); - frontend.recv_iopub_idle(); + recv_iopub_busy!(frontend); + recv_iopub_idle!(frontend); } #[test] @@ -27,15 +37,15 @@ fn test_execute_request() { let code = "42"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] 42"); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] 42"); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -44,26 +54,26 @@ fn test_execute_request_empty() { let code = ""; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); // Equivalent to invisible output let code = "invisible(1)"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -72,15 +82,15 @@ fn test_execute_request_multiple_lines() { let code = "1 +\n 2+\n 3"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] 6"); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] 6"); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count) + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count) } #[test] @@ -89,19 +99,17 @@ fn test_execute_request_incomplete() { let code = "1 +"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert!(frontend - .recv_iopub_execute_error() - .contains("Can't execute incomplete input")); + assert!(recv_iopub_execute_error!(frontend).contains("Can't execute incomplete input")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); assert_eq!( - frontend.recv_shell_execute_reply_exception(), + recv_shell_execute_reply_exception!(frontend), input.execution_count ) } @@ -112,19 +120,17 @@ fn test_execute_request_incomplete_multiple_lines() { let code = "1 +\n2 +"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert!(frontend - .recv_iopub_execute_error() - .contains("Can't execute incomplete input")); + assert!(recv_iopub_execute_error!(frontend).contains("Can't execute incomplete input")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); assert_eq!( - frontend.recv_shell_execute_reply_exception(), + recv_shell_execute_reply_exception!(frontend), input.execution_count ) } @@ -135,29 +141,27 @@ fn test_execute_request_browser() { let code = "browser()"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert!(frontend - .recv_iopub_execute_result() - .contains("Called from: top level")); + assert!(recv_iopub_execute_result!(frontend).contains("Called from: top level")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); let code = "Q"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -171,40 +175,38 @@ fn test_execute_request_browser_error() { let code = "browser()"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert!(frontend - .recv_iopub_execute_result() - .contains("Called from: top level")); + assert!(recv_iopub_execute_result!(frontend).contains("Called from: top level")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); frontend.send_execute_request("stop('foobar')", ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, "stop('foobar')"); - frontend.recv_iopub_stream_stderr("Error: foobar\n"); - frontend.recv_iopub_idle(); + recv_iopub_stream_stderr!(frontend, "Error: foobar\n"); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); let code = "Q"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -213,41 +215,39 @@ fn test_execute_request_browser_incomplete() { let code = "browser()"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert!(frontend - .recv_iopub_execute_result() - .contains("Called from: top level")); + assert!(recv_iopub_execute_result!(frontend).contains("Called from: top level")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); let code = "1 +"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_stream_stderr("Error: \nCan't execute incomplete input:\n1 +\n"); - frontend.recv_iopub_idle(); + recv_iopub_stream_stderr!(frontend, "Error: \nCan't execute incomplete input:\n1 +\n"); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); let code = "Q"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } // Test that a multiline input in the browser doesn't throw off our prompt info @@ -264,42 +264,42 @@ fn <- function() { } fn()"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); // We aren't at top level, so this comes as an iopub stream - frontend.recv_iopub_stream_stdout("Called from: fn()\n"); - frontend.recv_iopub_idle(); + recv_iopub_stream_stdout!(frontend, "Called from: fn()\n"); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); // Execute a multiline statement while paused in the debugger let code = "1 + 1"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); // Also received as iopub stream because we aren't at top level, we are in the debugger - frontend.recv_iopub_stream_stdout("[1] 2\n"); - frontend.recv_iopub_idle(); + recv_iopub_stream_stdout!(frontend, "[1] 2\n"); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); let code = "Q"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -308,46 +308,44 @@ fn test_execute_request_browser_stdin() { let code = "browser()"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert!(frontend - .recv_iopub_execute_result() - .contains("Called from: top level")); + assert!(recv_iopub_execute_result!(frontend).contains("Called from: top level")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); let options = ExecuteRequestOptions { allow_stdin: true }; let code = "readline('prompt>')"; frontend.send_execute_request(code, options); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - let prompt = frontend.recv_stdin_input_request(); + let prompt = recv_stdin_input_request!(frontend); assert_eq!(prompt, String::from("prompt>")); frontend.send_stdin_input_reply(String::from("hi")); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] \"hi\""); - frontend.recv_iopub_idle(); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] \"hi\""); + recv_iopub_idle!(frontend); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); let code = "Q"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -355,16 +353,16 @@ fn test_execute_request_error() { let frontend = DummyArkFrontend::lock(); frontend.send_execute_request("stop('foobar')", ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, "stop('foobar')"); - assert!(frontend.recv_iopub_execute_error().contains("foobar")); + assert!(recv_iopub_execute_error!(frontend).contains("foobar")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); assert_eq!( - frontend.recv_shell_execute_reply_exception(), + recv_shell_execute_reply_exception!(frontend), input.execution_count ); } @@ -374,18 +372,18 @@ fn test_execute_request_error_multiple_expressions() { let frontend = DummyArkFrontend::lock(); frontend.send_execute_request("1\nstop('foobar')\n2", ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, "1\nstop('foobar')\n2"); - frontend.recv_iopub_stream_stdout("[1] 1\n"); - assert!(frontend.recv_iopub_execute_error().contains("foobar")); + recv_iopub_stream_stdout!(frontend, "[1] 1\n"); + assert!(recv_iopub_execute_error!(frontend).contains("foobar")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); assert_eq!( - frontend.recv_shell_execute_reply_exception(), + recv_shell_execute_reply_exception!(frontend), input.execution_count ); } @@ -396,22 +394,22 @@ fn test_execute_request_multiple_expressions() { let code = "1\nprint(2)\n3"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); // Printed output - frontend.recv_iopub_stream_stdout("[1] 1\n[1] 2\n"); + recv_iopub_stream_stdout!(frontend, "[1] 1\n[1] 2\n"); // In console mode, we get output for all intermediate results. That's not // the case in notebook mode where only the final result is emitted. Note // that `print()` returns invisibly. - assert_eq!(frontend.recv_iopub_execute_result(), "[1] 3"); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] 3"); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -425,19 +423,17 @@ fn test_execute_request_single_line_buffer_overflow() { let aaa = "a".repeat(4096); let code = format!("quote(\n{aaa}\n)"); frontend.send_execute_request(code.as_str(), ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert!(frontend - .recv_iopub_execute_error() - .contains("Can't pass console input on to R")); + assert!(recv_iopub_execute_error!(frontend).contains("Can't pass console input on to R")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); assert_eq!( - frontend.recv_shell_execute_reply_exception(), + recv_shell_execute_reply_exception!(frontend), input.execution_count ); } @@ -450,21 +446,21 @@ fn test_stdin_basic_prompt() { let code = "readline('prompt>')"; frontend.send_execute_request(code, options); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - let prompt = frontend.recv_stdin_input_request(); + let prompt = recv_stdin_input_request!(frontend); assert_eq!(prompt, String::from("prompt>")); frontend.send_stdin_input_reply(String::from("hi")); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] \"hi\""); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] \"hi\""); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -475,21 +471,21 @@ fn test_stdin_followed_by_an_expression_on_the_same_line() { let code = "val <- readline('prompt>'); paste0(val,'-there')"; frontend.send_execute_request(code, options); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - let prompt = frontend.recv_stdin_input_request(); + let prompt = recv_stdin_input_request!(frontend); assert_eq!(prompt, String::from("prompt>")); frontend.send_stdin_input_reply(String::from("hi")); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] \"hi-there\""); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] \"hi-there\""); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -500,23 +496,23 @@ fn test_stdin_followed_by_an_expression_on_the_next_line() { let code = "1\nval <- readline('prompt>')\npaste0(val,'-there')"; frontend.send_execute_request(code, options); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_stream_stdout("[1] 1\n"); + recv_iopub_stream_stdout!(frontend, "[1] 1\n"); - let prompt = frontend.recv_stdin_input_request(); + let prompt = recv_stdin_input_request!(frontend); assert_eq!(prompt, String::from("prompt>")); frontend.send_stdin_input_reply(String::from("hi")); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] \"hi-there\""); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] \"hi-there\""); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -527,28 +523,26 @@ fn test_stdin_single_line_buffer_overflow() { let code = "1\nreadline('prompt>')"; frontend.send_execute_request(code, options); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_stream_stdout("[1] 1\n"); + recv_iopub_stream_stdout!(frontend, "[1] 1\n"); - let prompt = frontend.recv_stdin_input_request(); + let prompt = recv_stdin_input_request!(frontend); assert_eq!(prompt, String::from("prompt>")); // Would overflow R's internal buffer let aaa = "a".repeat(4096); frontend.send_stdin_input_reply(aaa); - assert!(frontend - .recv_iopub_execute_error() - .contains("Can't pass console input on to R")); + assert!(recv_iopub_execute_error!(frontend).contains("Can't pass console input on to R")); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); assert_eq!( - frontend.recv_shell_execute_reply_exception(), + recv_shell_execute_reply_exception!(frontend), input.execution_count ); } @@ -561,33 +555,34 @@ fn test_stdin_from_menu() { let code = "menu(c('a', 'b'))\n3"; frontend.send_execute_request(code, options); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); // R emits this before asking for your selection - frontend.recv_iopub_stream_stdout( + recv_iopub_stream_stdout!( + frontend, " 1: a 2: b -", +" ); - let prompt = frontend.recv_stdin_input_request(); + let prompt = recv_stdin_input_request!(frontend); assert_eq!(prompt, String::from("Selection: ")); frontend.send_stdin_input_reply(String::from("b")); // Position of selection is returned - frontend.recv_iopub_stream_stdout("[1] 2\n"); + recv_iopub_stream_stdout!(frontend, "[1] 2\n"); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] 3"); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] 3"); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -602,11 +597,11 @@ fn test_env_vars() { identical(Sys.getenv('R_DOC_DIR'), R.home('doc')) )"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } diff --git a/crates/ark/tests/plots.rs b/crates/ark/tests/plots.rs index e3f0091e1..4da059586 100644 --- a/crates/ark/tests/plots.rs +++ b/crates/ark/tests/plots.rs @@ -1,4 +1,11 @@ use amalthea::fixtures::dummy_frontend::ExecuteRequestOptions; +use amalthea::recv_iopub_busy; +use amalthea::recv_iopub_display_data; +use amalthea::recv_iopub_execute_input; +use amalthea::recv_iopub_execute_result; +use amalthea::recv_iopub_idle; +use amalthea::recv_iopub_update_display_data; +use amalthea::recv_shell_execute_reply; use ark::fixtures::DummyArkFrontend; #[test] @@ -7,15 +14,15 @@ fn test_basic_plot() { let code = "plot(1:10)"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_display_data(); + recv_iopub_display_data!(frontend); - frontend.recv_iopub_idle(); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + recv_iopub_idle!(frontend); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -28,19 +35,19 @@ for (i in 1:5) { }"#; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_display_data(); - frontend.recv_iopub_display_data(); - frontend.recv_iopub_display_data(); - frontend.recv_iopub_display_data(); - frontend.recv_iopub_display_data(); + recv_iopub_display_data!(frontend); + recv_iopub_display_data!(frontend); + recv_iopub_display_data!(frontend); + recv_iopub_display_data!(frontend); + recv_iopub_display_data!(frontend); - frontend.recv_iopub_idle(); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + recv_iopub_idle!(frontend); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -68,16 +75,16 @@ if (file.exists(temp_file)) { "#; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_display_data(); - frontend.recv_iopub_display_data(); + recv_iopub_display_data!(frontend); + recv_iopub_display_data!(frontend); - frontend.recv_iopub_idle(); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + recv_iopub_idle!(frontend); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -96,18 +103,18 @@ par(mfrow = c(1, 1)) "#; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_display_data(); - frontend.recv_iopub_update_display_data(); - frontend.recv_iopub_update_display_data(); - frontend.recv_iopub_display_data(); + recv_iopub_display_data!(frontend); + recv_iopub_update_display_data!(frontend); + recv_iopub_update_display_data!(frontend); + recv_iopub_display_data!(frontend); - frontend.recv_iopub_idle(); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + recv_iopub_idle!(frontend); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } #[test] @@ -117,51 +124,51 @@ fn test_graphics_device_initialization() { // On startup we are in the interactive list, but not current device let code = "'.ark.graphics.device' %in% grDevices::deviceIsInteractive()"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); - let input = frontend.recv_iopub_execute_input(); + recv_iopub_busy!(frontend); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] TRUE"); - frontend.recv_iopub_idle(); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] TRUE"); + recv_iopub_idle!(frontend); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); // The current device is `"null device"` let code = ".Device"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); - let input = frontend.recv_iopub_execute_input(); + recv_iopub_busy!(frontend); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] \"null device\""); - frontend.recv_iopub_idle(); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] \"null device\""); + recv_iopub_idle!(frontend); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); // The current `"null device"` is not interactive let code = "grDevices::dev.interactive()"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); - let input = frontend.recv_iopub_execute_input(); + recv_iopub_busy!(frontend); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] FALSE"); - frontend.recv_iopub_idle(); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] FALSE"); + recv_iopub_idle!(frontend); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); // But `orNone = TRUE` looks at `options(device =)` in this case, which // we set to us, so this works (and is used by `demo(graphics)`) let code = "grDevices::dev.interactive(orNone = TRUE)"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); - let input = frontend.recv_iopub_execute_input(); + recv_iopub_busy!(frontend); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] TRUE"); - frontend.recv_iopub_idle(); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] TRUE"); + recv_iopub_idle!(frontend); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); // Now simulate the user creating a plot, which makes us the current graphics device let code = "x <- .ark.graphics.device(); grDevices::dev.interactive()"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); - let input = frontend.recv_iopub_execute_input(); + recv_iopub_busy!(frontend); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] TRUE"); - frontend.recv_iopub_idle(); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] TRUE"); + recv_iopub_idle!(frontend); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } diff --git a/crates/ark/tests/r-profile-cat.rs b/crates/ark/tests/r-profile-cat.rs index 3592a926f..21c7834c0 100644 --- a/crates/ark/tests/r-profile-cat.rs +++ b/crates/ark/tests/r-profile-cat.rs @@ -1,5 +1,6 @@ use std::io::Write; +use amalthea::recv_iopub_stream_stdout; use ark::fixtures::DummyArkFrontendRprofile; // SAFETY: @@ -30,5 +31,5 @@ fn test_r_profile_can_cat() { // Ok, load up R now. It should `cat()` the `message` over iopub. let frontend = DummyArkFrontendRprofile::lock(); - frontend.recv_iopub_stream_stdout(message) + recv_iopub_stream_stdout!(frontend, message) } diff --git a/crates/ark/tests/r-profile-once.rs b/crates/ark/tests/r-profile-once.rs index 17fa67f49..07f0c73d0 100644 --- a/crates/ark/tests/r-profile-once.rs +++ b/crates/ark/tests/r-profile-once.rs @@ -1,6 +1,11 @@ use std::io::Write; use amalthea::fixtures::dummy_frontend::ExecuteRequestOptions; +use amalthea::recv_iopub_busy; +use amalthea::recv_iopub_execute_input; +use amalthea::recv_iopub_execute_result; +use amalthea::recv_iopub_idle; +use amalthea::recv_shell_execute_reply; use ark::fixtures::DummyArkFrontendRprofile; // SAFETY: @@ -38,13 +43,13 @@ if (exists("x")) { let frontend = DummyArkFrontendRprofile::lock(); frontend.send_execute_request("x", ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, "x"); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] 1"); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] 1"); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); } diff --git a/crates/ark/tests/repos-auto.rs b/crates/ark/tests/repos-auto.rs index b9e29ca1d..94c955837 100644 --- a/crates/ark/tests/repos-auto.rs +++ b/crates/ark/tests/repos-auto.rs @@ -8,6 +8,11 @@ use std::io::Write; use amalthea::fixtures::dummy_frontend::ExecuteRequestOptions; +use amalthea::recv_iopub_busy; +use amalthea::recv_iopub_execute_input; +use amalthea::recv_iopub_execute_result; +use amalthea::recv_iopub_idle; +use amalthea::recv_shell_execute_reply; use ark::fixtures::DummyArkFrontendDefaultRepos; /// Using the automatic repos setting, the default CRAN repo should be set to the global RStudio @@ -28,16 +33,16 @@ fn test_auto_repos() { let code = r#"getOption("repos")[["CRAN"]]"#; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); assert_eq!( - frontend.recv_iopub_execute_result(), + recv_iopub_execute_result!(frontend), r#"[1] "https://cran.rstudio.com/""# ); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count) + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count) } diff --git a/crates/ark/tests/repos-conf-file.rs b/crates/ark/tests/repos-conf-file.rs index e31d68f74..4c07f6479 100644 --- a/crates/ark/tests/repos-conf-file.rs +++ b/crates/ark/tests/repos-conf-file.rs @@ -7,6 +7,11 @@ use std::io::Write; use amalthea::fixtures::dummy_frontend::ExecuteRequestOptions; +use amalthea::recv_iopub_busy; +use amalthea::recv_iopub_execute_input; +use amalthea::recv_iopub_execute_result; +use amalthea::recv_iopub_idle; +use amalthea::recv_shell_execute_reply; use ark::fixtures::DummyArkFrontendDefaultRepos; /// Using a configuration file, set the default CRAN repo to a custom value, @@ -36,31 +41,31 @@ Internal=https://internal.cran.mirror/ let code = r#"getOption("repos")[["CRAN"]]"#; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); assert_eq!( - frontend.recv_iopub_execute_result(), + recv_iopub_execute_result!(frontend), r#"[1] "https://my.cran.mirror/""# ); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); let code = r#"getOption("repos")[["Internal"]]"#; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); assert_eq!( - frontend.recv_iopub_execute_result(), + recv_iopub_execute_result!(frontend), r#"[1] "https://internal.cran.mirror/""# ); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count) + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count) } diff --git a/crates/ark/tests/rstudioapi.rs b/crates/ark/tests/rstudioapi.rs index 4c5c0b1be..497265b6a 100644 --- a/crates/ark/tests/rstudioapi.rs +++ b/crates/ark/tests/rstudioapi.rs @@ -1,4 +1,9 @@ use amalthea::fixtures::dummy_frontend::ExecuteRequestOptions; +use amalthea::recv_iopub_busy; +use amalthea::recv_iopub_execute_input; +use amalthea::recv_iopub_execute_result; +use amalthea::recv_iopub_idle; +use amalthea::recv_shell_execute_reply; use ark::fixtures::DummyArkFrontend; #[test] @@ -18,18 +23,18 @@ fn test_get_version() { let code = "as.character(rstudioapi::getVersion())"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); assert_eq!( - frontend.recv_iopub_execute_result(), + recv_iopub_execute_result!(frontend), format!("[1] \"{value}\"") ); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count) + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count) } #[test] @@ -49,42 +54,42 @@ fn test_get_mode() { let code = "rstudioapi::getMode()"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); assert_eq!( - frontend.recv_iopub_execute_result(), + recv_iopub_execute_result!(frontend), format!("[1] \"{value}\"") ); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count) + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count) } fn set_var(key: &str, value: &str, frontend: &DummyArkFrontend) { let code = format!("Sys.setenv({key} = \"{value}\")"); frontend.send_execute_request(code.as_str(), ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count) + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count) } fn has_rstudioapi(frontend: &DummyArkFrontend) -> bool { let code = ".ps.is_installed('rstudioapi')"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - let result = frontend.recv_iopub_execute_result(); + let result = recv_iopub_execute_result!(frontend); let out = if result == "[1] TRUE" { true @@ -94,9 +99,9 @@ fn has_rstudioapi(frontend: &DummyArkFrontend) -> bool { panic!("Expected `TRUE` or `FALSE`, got '{result}'."); }; - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count); + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count); out } diff --git a/crates/ark/tests/stack.rs b/crates/ark/tests/stack.rs index 3766ae088..cd49576a7 100644 --- a/crates/ark/tests/stack.rs +++ b/crates/ark/tests/stack.rs @@ -1,4 +1,9 @@ use amalthea::fixtures::dummy_frontend::ExecuteRequestOptions; +use amalthea::recv_iopub_busy; +use amalthea::recv_iopub_execute_input; +use amalthea::recv_iopub_execute_result; +use amalthea::recv_iopub_idle; +use amalthea::recv_shell_execute_reply; use ark::fixtures::DummyArkFrontend; // These tests assert that we've correctly turned off the `R_StackLimit` check during integration @@ -11,15 +16,15 @@ fn test_stack_info_size() { let code = "Cstack_info()[['size']]"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] NA"); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] NA"); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count) + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count) } #[test] @@ -28,13 +33,13 @@ fn test_stack_info_current() { let code = "Cstack_info()[['current']]"; frontend.send_execute_request(code, ExecuteRequestOptions::default()); - frontend.recv_iopub_busy(); + recv_iopub_busy!(frontend); - let input = frontend.recv_iopub_execute_input(); + let input = recv_iopub_execute_input!(frontend); assert_eq!(input.code, code); - assert_eq!(frontend.recv_iopub_execute_result(), "[1] NA"); + assert_eq!(recv_iopub_execute_result!(frontend), "[1] NA"); - frontend.recv_iopub_idle(); + recv_iopub_idle!(frontend); - assert_eq!(frontend.recv_shell_execute_reply(), input.execution_count) + assert_eq!(recv_shell_execute_reply!(frontend), input.execution_count) }