diff --git a/.gitignore b/.gitignore index 409c3fb234..92eec21d12 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,6 @@ **/*.so .Rproj.user **/tasks.json + +# CLion support files +**/.idea diff --git a/tests/extendrtests/NAMESPACE b/tests/extendrtests/NAMESPACE index 81be91f8f3..f804b7780d 100644 --- a/tests/extendrtests/NAMESPACE +++ b/tests/extendrtests/NAMESPACE @@ -1,5 +1,4 @@ # Generated by roxygen2: do not edit by hand -export(add_ints) -export(hello) +export(hello_world) useDynLib(extendrtests, .registration = TRUE) diff --git a/tests/extendrtests/R/wrappers.R b/tests/extendrtests/R/wrappers.R index b3fed5f663..a8e0d0cc5b 100644 --- a/tests/extendrtests/R/wrappers.R +++ b/tests/extendrtests/R/wrappers.R @@ -1,15 +1,8 @@ -#' Wrappers for Rust functions. +#' Wrappers for Rust test functions. #' -#' Wrappers for Rust functions. +#' Wrappers for Rust test functions. #' @rdname wrappers #' @export -hello <- function() { - .Call("wrap__hello") +hello_world <- function() { + .Call("wrap__hello_world") } - -#' @rdname wrappers -#' @param x,y parameters -#' @export -add_ints <- function(x, y) { - .Call("wrap__add_ints", x, y) -} \ No newline at end of file diff --git a/tests/extendrtests/man/wrappers.Rd b/tests/extendrtests/man/wrappers.Rd index a2c74a366f..4b45ffc3ee 100644 --- a/tests/extendrtests/man/wrappers.Rd +++ b/tests/extendrtests/man/wrappers.Rd @@ -1,17 +1,11 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/wrappers.R -\name{hello} -\alias{hello} -\alias{add_ints} -\title{Wrappers for Rust functions.} +\name{hello_world} +\alias{hello_world} +\title{Wrappers for Rust test functions.} \usage{ -hello() - -add_ints(x, y) -} -\arguments{ -\item{x, y}{parameters} +hello_world() } \description{ -Wrappers for Rust functions. +Wrappers for Rust test functions. } diff --git a/tests/extendrtests/src/rust/Cargo.toml b/tests/extendrtests/src/rust/Cargo.toml index 0ee70d704f..4afc483df7 100644 --- a/tests/extendrtests/src/rust/Cargo.toml +++ b/tests/extendrtests/src/rust/Cargo.toml @@ -16,7 +16,7 @@ crate-type = ["staticlib"] extendr-api = "*" [patch.crates-io] -extendr-api = { git = "https://github.com/clauswilke/extendr", branch = "reg-forwarding" } -extendr-engine = { git = "https://github.com/clauswilke/extendr", branch = "reg-forwarding" } -extendr-macros = { git = "https://github.com/clauswilke/extendr", branch = "reg-forwarding" } +extendr-api = { git = "https://github.com/extendr/extendr" } +extendr-engine = { git = "https://github.com/extendr/extendr" } +extendr-macros = { git = "https://github.com/extendr/extendr" } #libR-sys = { git = "https://github.com/extendr/libR-sys" } diff --git a/tests/extendrtests/src/rust/src/lib.rs b/tests/extendrtests/src/rust/src/lib.rs index b840db6c3e..be75ee6a3c 100644 --- a/tests/extendrtests/src/rust/src/lib.rs +++ b/tests/extendrtests/src/rust/src/lib.rs @@ -1,19 +1,28 @@ use extendr_api::*; #[extendr] -fn hello() -> &'static str { - "hello" +fn hello_world() -> &'static str { + "Hello world!" } +// functions to test input/output conversion #[extendr] -fn add_ints(x:i32, y:i32) -> i32 { - x + y -} +fn double_scalar(x: f64) -> f64 { x } +#[extendr] +fn int_scalar(x: i32) -> i32 { x } +#[extendr] +fn bool_scalar(x: bool) -> bool { x } +#[extendr] +fn char_scalar(x: String) -> String { x } // Macro to generate exports extendr_module! { mod extendrtests; - fn hello; - fn add_ints; + fn hello_world; + + fn double_scalar; + fn int_scalar; + fn bool_scalar; + fn char_scalar; } diff --git a/tests/extendrtests/tests/testthat/test-type-conversion.R b/tests/extendrtests/tests/testthat/test-type-conversion.R new file mode 100644 index 0000000000..e1287cde18 --- /dev/null +++ b/tests/extendrtests/tests/testthat/test-type-conversion.R @@ -0,0 +1,31 @@ +test_that("Conversion of R types to Rust types and vice versa works", { + expect_equal(.Call(wrap__double_scalar, .45), .45) + expect_equal(.Call(wrap__double_scalar, 15L), 15) + expect_error(.Call(wrap__double_scalar, TRUE), "unable to convert") + expect_error(.Call(wrap__double_scalar, "abcxyz"), "unable to convert") + expect_error(.Call(wrap__double_scalar, NA_real_), "Input must not be NA") + expect_error(.Call(wrap__double_scalar, c(.45, .46)), "Input must be of length 1") + + expect_equal(.Call(wrap__int_scalar, 15L), 15L) + expect_equal(.Call(wrap__int_scalar, 4.4), 4L) # is this deliberate? seems dangerous + expect_error(.Call(wrap__int_scalar, TRUE), "unable to convert") + expect_error(.Call(wrap__int_scalar, "abcxyz"), "unable to convert") + expect_error(.Call(wrap__int_scalar, NA_integer_), "Input must not be NA") + expect_error(.Call(wrap__int_scalar, 1L:5L), "Input must be of length 1") + + expect_equal(.Call(wrap__bool_scalar, TRUE), TRUE) + expect_equal(.Call(wrap__bool_scalar, FALSE), FALSE) + expect_error(.Call(wrap__bool_scalar, .45), "Not a logical object") + expect_error(.Call(wrap__bool_scalar, 15L), "Not a logical object") + expect_error(.Call(wrap__bool_scalar, "abcxyz"), "Not a logical object") + expect_error(.Call(wrap__bool_scalar, NA), "Input must not be NA") + expect_error(.Call(wrap__bool_scalar, c(TRUE, FALSE, TRUE)), "Input must be of length 1") + + expect_equal(.Call(wrap__char_scalar, "abcxyz"), "abcxyz") + expect_error(.Call(wrap__char_scalar, .45), "not a string object") + expect_error(.Call(wrap__char_scalar, 15L), "not a string object") + expect_error(.Call(wrap__char_scalar, TRUE), "not a string object") + expect_error(.Call(wrap__char_scalar, NA_character_), "Input must not be NA") + expect_error(.Call(wrap__char_scalar, c("hello", "world")), "not a string object") # why this error message and not "Input must be of length 1"? +}) + diff --git a/tests/extendrtests/tests/testthat/test-wrappers.R b/tests/extendrtests/tests/testthat/test-wrappers.R index ccf4283815..3a37850dce 100644 --- a/tests/extendrtests/tests/testthat/test-wrappers.R +++ b/tests/extendrtests/tests/testthat/test-wrappers.R @@ -1,4 +1,3 @@ -test_that("Call to Rust functions work", { - expect_equal(hello(), "hello") - expect_equal(add_ints(3L, 5L), 8L) +test_that("Call to Rust via wrapper functions works", { + expect_equal(hello_world(), "Hello world!") })