Skip to content

Commit 718812d

Browse files
Add meaningful tests to rextendr (#25)
* Enabling tests * Updating workflow * Configuring Rust on Windows * Running tests within rcmdcheck * Cleanup * Testing rust function name resolution * Testing function with no return * Testing Windows only * Trying msvc toolchain * Cleanup * Removed debug workflow triggers * Checking NOT_CRAN once
1 parent fd64ee1 commit 718812d

File tree

4 files changed

+87
-29
lines changed

4 files changed

+87
-29
lines changed

.github/workflows/R-CMD-check.yaml

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,40 @@ jobs:
1414
R-CMD-check:
1515
runs-on: ${{ matrix.config.os }}
1616

17-
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
17+
name: ${{ matrix.config.os }} (${{ matrix.config.r }} / ${{ matrix.config.rust-version }})
1818

1919
strategy:
2020
fail-fast: false
2121
matrix:
2222
config:
23-
- {os: windows-latest, r: 'release'}
24-
- {os: macOS-latest, r: 'release'}
25-
- {os: ubuntu-20.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"}
26-
- {os: ubuntu-20.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"}
23+
- {os: windows-latest, r: 'release', rust-version: 'stable-msvc'}
24+
- {os: macOS-latest, r: 'release', rust-version: 'stable'}
25+
- {os: ubuntu-20.04, r: 'release', rust-version: 'stable', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"}
26+
- {os: ubuntu-20.04, r: 'devel', rust-version: 'stable', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"}
2727

2828
env:
2929
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
3030
RSPM: ${{ matrix.config.rspm }}
3131

3232
steps:
3333
- uses: actions/checkout@v2
34+
35+
- name: Set up Rust
36+
uses: actions-rs/toolchain@v1
37+
with:
38+
toolchain: ${{ matrix.config.rust-version }}
39+
default: true
3440

35-
- uses: r-lib/actions/setup-r@v1
41+
# Uses @master branch to address rtools path issue
42+
# https://github.com/r-lib/actions/issues/228
43+
- name: Set up R
44+
uses: r-lib/actions/setup-r@master
3645
with:
3746
r-version: ${{ matrix.config.r }}
47+
windows-path-include-mingw: false
3848

39-
- uses: r-lib/actions/setup-pandoc@v1
49+
- name: Set up pandoc
50+
uses: r-lib/actions/setup-pandoc@v1
4051

4152
- name: Query dependencies
4253
run: |
@@ -45,37 +56,49 @@ jobs:
4556
writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version")
4657
shell: Rscript {0}
4758

48-
- name: Cache R packages
49-
if: runner.os != 'Windows'
59+
- name: Cache R packages (not Windows)
60+
if: startsWith(runner.os, 'Windows') == false
5061
uses: actions/cache@v2
5162
with:
5263
path: ${{ env.R_LIBS_USER }}
5364
key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }}
5465
restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-
5566

56-
- name: Install system dependencies
57-
if: runner.os == 'Linux'
67+
- name: Configure Windows
68+
if: startsWith(runner.os, 'Windows')
69+
run: |
70+
rustup target add x86_64-pc-windows-gnu
71+
rustup target add i686-pc-windows-gnu
72+
echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
73+
echo "C:\msys64\mingw32\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
74+
shell: pwsh
75+
76+
- name: Configure Linux
77+
if: startsWith(runner.os, 'Linux')
5878
run: |
5979
while read -r cmd
6080
do
6181
eval sudo $cmd
6282
done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))')
6383
84+
6485
- name: Install dependencies
6586
run: |
6687
remotes::install_deps(dependencies = TRUE)
6788
remotes::install_cran("rcmdcheck")
6889
shell: Rscript {0}
6990

7091
- name: Check
92+
id: rcmd_check
7193
env:
7294
_R_CHECK_CRAN_INCOMING_REMOTE_: false
73-
run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check")
95+
run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran", "--force-multiarch"), error_on = "warning", check_dir = "check")
7496
shell: Rscript {0}
7597

7698
- name: Upload check results
7799
if: failure()
78100
uses: actions/upload-artifact@main
79101
with:
80-
name: ${{ runner.os }}-r${{ matrix.config.r }}-results
102+
name: ${{ runner.os }}-r${{ matrix.config.r }}-rust${{ matrix.config.rust-version }}-results
81103
path: check
104+

tests/testthat.R

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ library(testthat)
22
library(rextendr)
33

44
# no need to run tests if cargo isn't installed.
5-
result <- system2("cargo")
6-
if (result == 0L) {
5+
cargo_available <- system2("cargo") == 0L
6+
not_cran <- identical(Sys.getenv("NOT_CRAN"), "true")
7+
8+
if (cargo_available && not_cran) {
79
test_check("rextendr")
8-
}
10+
}

tests/testthat/test-name-override.R

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
test_that("Multiple rust functions with the same name", {
2+
3+
rust_src_1 <- "
4+
#[extendr]
5+
fn rust_fn_1() -> i32 { 1i32 }
6+
7+
#[extendr]
8+
fn rust_fn_2() -> i32 { 2i32 }
9+
"
10+
11+
rust_src_2 <- "
12+
#[extendr]
13+
fn rust_fn_2() -> i32 { 20i32 }
14+
15+
#[extendr]
16+
fn rust_fn_3() -> i32 { 30i32 }
17+
"
18+
19+
rust_source(code = rust_src_1, quiet = FALSE)
20+
21+
# At this point:
22+
# fn1 -> 1
23+
# fn2 -> 2
24+
# fn3 -> (not exported)
25+
26+
expect_equal(rust_fn_1(), 1L)
27+
expect_equal(rust_fn_2(), 2L)
28+
29+
rust_source(code = rust_src_2, quiet = FALSE)
30+
31+
# At this point:
32+
# fn1 -> 1 (unchanged)
33+
# fn2 -> 20 (changed)
34+
# fn3 -> 30 (new function)
35+
36+
expect_equal(rust_fn_1(), 1L)
37+
expect_equal(rust_fn_2(), 20L)
38+
expect_equal(rust_fn_3(), 30L)
39+
40+
41+
})

tests/testthat/test-source.R

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
# implementation of actual tests will require updated extendr-api, extendr-macros, libR-sys
2-
# on crates.io.
3-
41
test_that("Testing the source", {
5-
skip("This would typically fail, unless changed to reflect paths /
6-
on host's machine. ")
7-
# some simple Rust code with two functions
8-
rust_src <- "use extendr_api::*;
92

3+
rust_src <- "
104
#[extendr]
115
fn hello() -> &'static str {
126
\"Hello, this string was created by Rust.\"
@@ -30,22 +24,20 @@ test_that("Testing the source", {
3024

3125
rust_source(
3226
code = rust_src,
33-
# use `patch.crates_io` argument to override crate locations
34-
patch.crates_io = c(
35-
'extendr-api = {path = "C:/Users/tpb398/Documents/GitHub/extendR/extendr-api"}',
36-
'extendr-macros = {path = "C:/Users/tpb398/Documents/GitHub/extendR/extendr-macros"}'
37-
),
3827
quiet = FALSE,
3928
cache_build = TRUE
4029
)
4130

4231
# call `hello()` function from R
43-
hello()
4432
#> [1] "Hello, this string was created by Rust."
33+
expect_equal(hello(), "Hello, this string was created by Rust.")
4534

4635
# call `add()` function from R
4736
expect_equal(add(14, 23), 37)
4837
#> [1] 37
4938
expect_equal(add(17, 42), 17 + 42)
5039

40+
# This function takes no arguments and invisibly return NULL
41+
expect_null(say_nothing())
42+
5143
})

0 commit comments

Comments
 (0)