Skip to content

Commit

Permalink
Add integration tests: scalar inputs/outputs (#91)
Browse files Browse the repository at this point in the history
* add integration tests: scalar inputs/outputs

* test reason for Windows fail

* try without wrapper

* do registration from C

* force symbols

* going all out

* switch decoy to Rust

* try forwarding routine registration

* clean up

* revert source back to github main
  • Loading branch information
clauswilke committed Dec 28, 2020
1 parent 62d0c15 commit 9752c7f
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 37 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@
**/*.so
.Rproj.user
**/tasks.json

# CLion support files
**/.idea
3 changes: 1 addition & 2 deletions tests/extendrtests/NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Generated by roxygen2: do not edit by hand

export(add_ints)
export(hello)
export(hello_world)
useDynLib(extendrtests, .registration = TRUE)
15 changes: 4 additions & 11 deletions tests/extendrtests/R/wrappers.R
Original file line number Diff line number Diff line change
@@ -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)
}
16 changes: 5 additions & 11 deletions tests/extendrtests/man/wrappers.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions tests/extendrtests/src/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
23 changes: 16 additions & 7 deletions tests/extendrtests/src/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
}
31 changes: 31 additions & 0 deletions tests/extendrtests/tests/testthat/test-type-conversion.R
Original file line number Diff line number Diff line change
@@ -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"?
})

5 changes: 2 additions & 3 deletions tests/extendrtests/tests/testthat/test-wrappers.R
Original file line number Diff line number Diff line change
@@ -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!")
})

0 comments on commit 9752c7f

Please sign in to comment.