Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use snapshots in a few more key places #393

Merged
merged 2 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions tests/testthat/_snaps/register.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,109 @@
# get_call_entries: returns an empty string for packages with .Call entries and NAMESPACE files

Code
call_entries
Output
[1] "/* .Call calls */"
[2] "extern SEXP bar(void);"
[3] ""
[4] "static const R_CallMethodDef CallEntries[] = {"
[5] " {\"bar\", (DL_FUNC) &bar, 0},"
[6] " {NULL, NULL, 0}"
[7] "};"

# get_call_entries: works with multiple register functions.

Code
cat(read_file(cpp_bindings))
Output
// Generated by cpp11: do not edit by hand
// clang-format off


#include "cpp11/declarations.hpp"
#include <R_ext/Visibility.h>

// multiple.cpp
int foo();
extern "C" SEXP _testPkg_foo() {
BEGIN_CPP11
return cpp11::as_sexp(foo());
END_CPP11
}
// multiple.cpp
double bar(bool run);
extern "C" SEXP _testPkg_bar(SEXP run) {
BEGIN_CPP11
return cpp11::as_sexp(bar(cpp11::as_cpp<cpp11::decay_t<bool>>(run)));
END_CPP11
}
// multiple.cpp
bool baz(bool run, int value);
extern "C" SEXP _testPkg_baz(SEXP run, SEXP value) {
BEGIN_CPP11
return cpp11::as_sexp(baz(cpp11::as_cpp<cpp11::decay_t<bool>>(run), cpp11::as_cpp<cpp11::decay_t<int>>(value)));
END_CPP11
}

extern "C" {
static const R_CallMethodDef CallEntries[] = {
{"_testPkg_bar", (DL_FUNC) &_testPkg_bar, 1},
{"_testPkg_baz", (DL_FUNC) &_testPkg_baz, 2},
{"_testPkg_foo", (DL_FUNC) &_testPkg_foo, 0},
{NULL, NULL, 0}
};
}

extern "C" attribute_visible void R_init_testPkg(DllInfo* dll){
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
R_forceSymbols(dll, TRUE);
}

# cpp_register: works with a package that registers a single c++ function

Code
cat(read_file(r_bindings))
Output
# Generated by cpp11: do not edit by hand

foo <- function() {
.Call(`_testPkg_foo`)
}

---

Code
cat(read_file(cpp_bindings))
Output
// Generated by cpp11: do not edit by hand
// clang-format off


#include "cpp11/declarations.hpp"
#include <R_ext/Visibility.h>

// single.cpp
int foo();
extern "C" SEXP _testPkg_foo() {
BEGIN_CPP11
return cpp11::as_sexp(foo());
END_CPP11
}

extern "C" {
static const R_CallMethodDef CallEntries[] = {
{"_testPkg_foo", (DL_FUNC) &_testPkg_foo, 0},
{NULL, NULL, 0}
};
}

extern "C" attribute_visible void R_init_testPkg(DllInfo* dll){
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
R_forceSymbols(dll, TRUE);
}

# cpp_register: can be run with messages

Code
Expand Down
101 changes: 8 additions & 93 deletions tests/testthat/test-register.R
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,18 @@ describe("get_call_entries", {
})

it("returns an empty string for packages with .Call entries and NAMESPACE files", {

# tools::package_native_routine_registration_skeleton is not available before R 3.4
skip_if(getRversion() < "3.4")
# R added `(void)` to the signature after R 4.3.0
skip_if(getRversion() < "4.3.0")

pkg <- local_package()
path <- pkg_path(pkg)
dir.create(file.path(path, "R"))

writeLines('foo <- function() .Call("bar")', file.path(path, "R", "foo.R"))
call_entries <- get_call_entries(path, get_funs(path)$name, get_package_name(path))
# R added `(void)` to the signature after R 4.2.1
expect_match(call_entries[2], "extern SEXP bar[(](void)?[)]")
expect_equal(
call_entries[4:7],
c("static const R_CallMethodDef CallEntries[] = {",
" {\"bar\", (DL_FUNC) &bar, 0},",
" {NULL, NULL, 0}",
"};"
)
)

expect_snapshot(call_entries)
})
it("works with multiple register functions.", {
pkg <- local_package()
Expand All @@ -78,51 +71,7 @@ describe("get_call_entries", {

cpp_register(p)
cpp_bindings <- file.path(p, "src", "cpp11.cpp")
expect_equal(read_file(cpp_bindings),
"// Generated by cpp11: do not edit by hand
// clang-format off


#include \"cpp11/declarations.hpp\"
#include <R_ext/Visibility.h>

// multiple.cpp
int foo();
extern \"C\" SEXP _testPkg_foo() {
BEGIN_CPP11
return cpp11::as_sexp(foo());
END_CPP11
}
// multiple.cpp
double bar(bool run);
extern \"C\" SEXP _testPkg_bar(SEXP run) {
BEGIN_CPP11
return cpp11::as_sexp(bar(cpp11::as_cpp<cpp11::decay_t<bool>>(run)));
END_CPP11
}
// multiple.cpp
bool baz(bool run, int value);
extern \"C\" SEXP _testPkg_baz(SEXP run, SEXP value) {
BEGIN_CPP11
return cpp11::as_sexp(baz(cpp11::as_cpp<cpp11::decay_t<bool>>(run), cpp11::as_cpp<cpp11::decay_t<int>>(value)));
END_CPP11
}

extern \"C\" {
static const R_CallMethodDef CallEntries[] = {
{\"_testPkg_bar\", (DL_FUNC) &_testPkg_bar, 1},
{\"_testPkg_baz\", (DL_FUNC) &_testPkg_baz, 2},
{\"_testPkg_foo\", (DL_FUNC) &_testPkg_foo, 0},
{NULL, NULL, 0}
};
}

extern \"C\" attribute_visible void R_init_testPkg(DllInfo* dll){
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
R_forceSymbols(dll, TRUE);
}
")
expect_snapshot(cat(read_file(cpp_bindings)))
})
})

Expand Down Expand Up @@ -569,44 +518,11 @@ describe("cpp_register", {

r_bindings <- file.path(p, "R", "cpp11.R")
expect_true(file.exists(r_bindings))
expect_equal(read_file(r_bindings),
"# Generated by cpp11: do not edit by hand
expect_snapshot(cat(read_file(r_bindings)))

foo <- function() {
.Call(`_testPkg_foo`)
}
")
cpp_bindings <- file.path(p, "src", "cpp11.cpp")
expect_true(file.exists(cpp_bindings))
expect_equal(read_file(cpp_bindings),
"// Generated by cpp11: do not edit by hand
// clang-format off


#include \"cpp11/declarations.hpp\"
#include <R_ext/Visibility.h>

// single.cpp
int foo();
extern \"C\" SEXP _testPkg_foo() {
BEGIN_CPP11
return cpp11::as_sexp(foo());
END_CPP11
}

extern \"C\" {
static const R_CallMethodDef CallEntries[] = {
{\"_testPkg_foo\", (DL_FUNC) &_testPkg_foo, 0},
{NULL, NULL, 0}
};
}

extern \"C\" attribute_visible void R_init_testPkg(DllInfo* dll){
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
R_forceSymbols(dll, TRUE);
}
")
expect_snapshot(cat(read_file(cpp_bindings)))
})

it("can be run without messages", {
Expand All @@ -617,7 +533,6 @@ extern \"C\" attribute_visible void R_init_testPkg(DllInfo* dll){
expect_silent(cpp_register(p, quiet = TRUE))
})


it("can be run with messages", {
local_reproducible_output()
pkg <- local_package()
Expand Down
Loading