context("c-registration.R")

test_that("update_c_registration does nothig if an init.c file already exists", {

  skip_if(getRversion() < "3.4")

  init_file <- test_path("testWithSrc", "src", "init.c")
  on.exit(unlink(init_file))

  writeLines('
#include <R.h>
#include <Rinternals.h>
#include <stdlib.h> // for NULL
#include <R_ext/Rdynload.h>


/* .Call calls */
extern SEXP add1(SEXP);
extern SEXP mult2(SEXP);

static const R_CallMethodDef CallEntries[] = {
    {"add1",  (DL_FUNC) &add1,  1},
    {"mult2", (DL_FUNC) &mult2, 1},
    {NULL, NULL, 0}
};

void R_init_testWithSrc(DllInfo *dll)
{
    R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
    R_useDynamicSymbols(dll, FALSE);
}', init_file)

  expect_equal(
    update_c_registration(test_path("testWithSrc")),
    character())
})

test_that("update_c_registration works", {

  skip_if(getRversion() < "3.4")

  init_file <- test_path("testWithSrc", "src", "init.c")
  on.exit(unlink(init_file))
  expect_false(file.exists(init_file))

  # Should return with no lines if there are no routines called
  expect_equal(update_c_registration(test_path("testWithSrc")), character())

  # Add a call and try to update again
  src_file <- test_path("testWithSrc", "R", "c.R")

  writeLines('
add1 <- function(x) {
  .Call("add1", x)
}', src_file)

  on.exit(unlink(src_file), add = TRUE)

  init_lines <- update_c_registration(test_path("testWithSrc"))

  expect_true(any(grepl("generated by pkgbuild", init_lines)))
  expect_true(any(grepl('"add1",.*[(]DL_FUNC[)] &add1', init_lines)))

  # update_c_registration should be idempotent if nothing has changed
  expect_equal(
    update_c_registration(test_path("testWithSrc")),
      init_lines)

  writeLines('
add1 <- function(x) {
  .Call("add1", x)
}

mult2 <- function(x) {
  .Call("mult2", x)
}', src_file)

  # update_c_registration should be idempotent if nothing has changed
  update_c_registration(test_path("testWithSrc"))

  init_src <- readLines(init_file)
  expect_true(any(grepl("generated by pkgbuild", init_src)))
  expect_true(any(grepl('"add1",.*[(]DL_FUNC[)] &add1', init_src)))
  expect_true(any(grepl('"mult2",.*[(]DL_FUNC[)] &mult2', init_src)))
})

test_that("check_namespace_registration", {
  expect_warning(check_namespace_registration(test_path("testWithSrc")))
})
