From 51169dda53200c2b4844376b65f406329aef421d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Fran=C3=A7ois?= Date: Tue, 14 Nov 2023 12:00:52 +0100 Subject: [PATCH] Test `is_complete_request()` (#37) * test for complete and incomplete code samples * using |> and _ * expose is_complete_request() * test invalid code samples --- share/jupyter/kernels/xr/resources/routines.R | 4 ++++ src/routines.cpp | 10 ++++++++++ src/xinterpreter.cpp | 1 + test/test_xr_kernel.py | 7 ++++--- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/share/jupyter/kernels/xr/resources/routines.R b/share/jupyter/kernels/xr/resources/routines.R index 8f400d9..35796f2 100644 --- a/share/jupyter/kernels/xr/resources/routines.R +++ b/share/jupyter/kernels/xr/resources/routines.R @@ -26,3 +26,7 @@ kernel_info_request <- function() { clear_output <- function(wait = FALSE) { invisible(.Call("xeusr_clear_output", isTRUE(wait), PACKAGE = "(embedding)")) } + +is_complete_request <- function(code) { + .Call("xeusr_is_complete_request", code, PACKAGE = "(embedding)") +} diff --git a/src/routines.cpp b/src/routines.cpp index a098c57..22097fa 100644 --- a/src/routines.cpp +++ b/src/routines.cpp @@ -81,6 +81,15 @@ SEXP clear_output(SEXP wait_) { return R_NilValue; } +SEXP is_complete_request(SEXP code_) { + std::string code = CHAR(STRING_ELT(code_, 0)); + auto is_complete = xeus_r::get_interpreter()->is_complete_request(code); + + SEXP out = PROTECT(Rf_mkString(is_complete.dump(4).c_str())); + Rf_classgets(out, Rf_mkString("json")); + UNPROTECT(1); + return out; +} } @@ -95,6 +104,7 @@ void register_r_routines() { {"xeusr_display_data" , (DL_FUNC) &routines::display_data , 2}, {"xeusr_update_display_data" , (DL_FUNC) &routines::update_display_data , 2}, {"xeusr_clear_output" , (DL_FUNC) &routines::clear_output , 1}, + {"xeusr_is_complete_request" , (DL_FUNC) &routines::is_complete_request , 1}, {NULL, NULL, 0} }; diff --git a/src/xinterpreter.cpp b/src/xinterpreter.cpp index 9dc2ba8..1120e23 100644 --- a/src/xinterpreter.cpp +++ b/src/xinterpreter.cpp @@ -128,6 +128,7 @@ nl::json interpreter::is_complete_request_impl(const std::string& code) return xeus::create_is_complete_reply("incomplete", ""); case PARSE_ERROR: + Rprintf("invalid"); return xeus::create_is_complete_reply("invalid", ""); } } diff --git a/test/test_xr_kernel.py b/test/test_xr_kernel.py index 559d27e..81ca1cc 100644 --- a/test/test_xr_kernel.py +++ b/test/test_xr_kernel.py @@ -30,12 +30,13 @@ def _execute_code(self, code, tests=True, silent=False, store_history=True): code_hello_world = "cat('hello, world')" # code_page_something = "?cat" completion_samples = [{"text": "H", "matches": {"Hello", "Hey", "Howdy"}}] - #complete_code_samples = ["hello, world"] code_execute_result = [{"code": "6*7", "result": "[1] 42"}] - #incomplete_code_samples = ["incomplete"] - #invalid_code_samples = ["invalid"] #code_inspect_sample = "print" + complete_code_samples = ["fun()", "1 + 2", "a %>% b", "a |> b()", "a |> b(c = _)"] + incomplete_code_samples = ["fun(", "1 + "] + invalid_code_samples = ["fun())"] + def test_stdout(self): self.flush_channels() reply, output_msgs = self.execute_helper(code="cat('hello, world')")