    print_code <- function(filename) {
      cat(readChar(filename, file.info(filename)$size))
    }

This vignette builds and tests some example projects which use mockcpp, to show you how you can include them in your package.

# Rcpp

We have created a toy random number generator using Rcpp

    print_code(
      system.file('testrcpp/src/code.h', package = 'mockcpp', mustWork = TRUE)
    )
    #> #include <Rcpp.h>
    #>
    #> class Random {
    #>   public:
    #>     virtual Rcpp::NumericVector uniform(size_t size) const {
    #>       return Rcpp::runif(size);
    #>     };
    #> };

Let's say we want to mock the output of our RNG. We can write a testthat test like so:

    print_code(
      system.file('testrcpp/src/test-example.cpp', package = 'mockcpp', mustWork = TRUE)
    )
    #> #include <Rcpp.h>
    #> #include <testthat.h>
    #> #include <mockcpp.h>
    #> #include "code.h"
    #>
    #> class MockRandom : public Random {
    #>   MAKE_CONST_MOCK1(uniform, Rcpp::NumericVector(size_t), override);
    #> };
    #>
    #> using trompeloeil::_;
    #>
    #> context("Can mock an RNG") {
    #>
    #>   test_that("you can change the return value") {
    #>     MockRandom rng;
    #>     auto mock_values = Rcpp::NumericVector::create(.1, .2, .3, .4, .5);
    #>     REQUIRE_CALL(rng, uniform(_)).RETURN(mock_values);
    #>     expect_true(Rcpp::is_true(Rcpp::all(rng.uniform(5) == mock_values)));
    #>   }
    #>
    #> }

We can then build our package and run the test to ensure our mocking works:

    # load test package
    pkgload::load_all(
      system.file('testrcpp', package = 'mockcpp', mustWork = TRUE)
    )
    #> ℹ Loading testrcpp
    #> Re-compiling testrcpp
    #>
    ─  installing *source* package ‘testrcpp’ ...
    #>

       ** using staged installation
    #>

       ** libs
    #>

       g++ -std=gnu++14 -I"/usr/local/lib/R/include" -DNDEBUG  -I'/usr/local/lib/R/site-library/testthat/include' -I'/tmp/RtmpPc0dLV/Rinsta1b2504ff/mockcpp/include' -I'/usr/local/lib/R/site-library/Rcpp/include' -I/usr/local/include   -fpic  -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g  -c test-example.cpp -o test-example.o
    #>

       g++ -std=gnu++14 -I"/usr/local/lib/R/include" -DNDEBUG  -I'/usr/local/lib/R/site-library/testthat/include' -I'/tmp/RtmpPc0dLV/Rinsta1b2504ff/mockcpp/include' -I'/usr/local/lib/R/site-library/Rcpp/include' -I/usr/local/include   -fpic  -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g  -c test-runner.cpp -o test-runner.o
    #>

       g++ -std=gnu++14 -shared -L/usr/local/lib/R/lib -L/usr/local/lib -o testrcpp.so test-example.o test-runner.o -L/usr/local/lib/R/lib -lR
    #>

       installing to /tmp/RtmptcByDM/devtools_install_647ae35f37/00LOCK-testrcpp/00new/testrcpp/libs
    #>

       ** checking absolute paths in shared objects and dynamic libraries
    #>

    ─  DONE (testrcpp)
    #>
    #> Warning: package 'testthat' was built under R version 4.0.3

    # run the test
    testthat::test_file(
      system.file(
        'testrcpp/tests/testthat/test-cpp.R',
        package = 'mockcpp',
        mustWork = TRUE
      )
    )
    #>
    #> ══ Testing test-cpp.R ══════════════════════════════════════════════════════════
    #>
    [ FAIL 0 | WARN 0 | SKIP 0 | PASS 0 ]
    [ FAIL 0 | WARN 0 | SKIP 0 | PASS 0 ]
    [ FAIL 0 | WARN 0 | SKIP 0 | PASS 1 ] Done!

# Cpp11

We can create a similar test for code written using cpp11.

Here's a toy RNG:

    print_code(
      system.file('testcpp11/src/code.h', package = 'mockcpp', mustWork = TRUE)
    )
    #> #include <cpp11/doubles.hpp>
    #> #include <cstdlib>
    #>
    #> class Random {
    #>   public:
    #>     virtual cpp11::doubles uniform(size_t size) const {
    #>       auto values = cpp11::writable::doubles(size);
    #>       // Newer GCC builds (Mac OS and Linux can use auto i = 0
    #>       // Older windows builds need to specify a type to avoid ambiguity errors 3/11/20 R 4.0.3
    #>       for (cpp11::writable::doubles::size_type i = 0; i < size; ++i) {
    #>         values[i] = ((double) std::rand() / (RAND_MAX)) + 1;
    #>       }
    #>       return values;
    #>     };
    #> };

And the corresponding test:

    print_code(
      system.file('testcpp11/src/test-example.cpp', package = 'mockcpp', mustWork = TRUE)
    )
    #> #include <cpp11/doubles.hpp>
    #> #include <testthat.h>
    #> #include <mockcpp.h>
    #> #include "code.h"
    #>
    #> class MockRandom : public Random {
    #>   MAKE_CONST_MOCK1(uniform, cpp11::doubles(size_t), override);
    #> };
    #>
    #> using trompeloeil::_;
    #>
    #> context("Can mock an RNG") {
    #>
    #>   test_that("you can change the return value") {
    #>     MockRandom rng;
    #>     auto mock_values = cpp11::writable::doubles{1, .2, .3, .4, .5};
    #>     auto size = mock_values.size();
    #>     REQUIRE_CALL(rng, uniform(_)).RETURN(mock_values);
    #>     auto actual = rng.uniform(size);
    #>     // Newer GCC builds (Mac OS and Linux can use auto i = 0
    #>     // Older windows builds need to specify a type to avoid ambiguity errors 3/11/20 R 4.0.3
    #>     for (cpp11::writable::doubles::size_type i = 0; i < size; ++i) {
    #>       expect_true(actual[i] == mock_values[i] );
    #>     }
    #>   }
    #>
    #> }

We can build and test this package in a similar way:

    # load test package
    pkgload::load_all(
      system.file('testcpp11', package = 'mockcpp', mustWork = TRUE)
    )
    #> ℹ Loading testcpp11
    #> Re-compiling testcpp11
    #>
    ─  installing *source* package ‘testcpp11’ ...
    #>

       ** using staged installation
    #>

       ** libs
    #>

       g++ -std=gnu++14 -I"/usr/local/lib/R/include" -DNDEBUG  -I'/usr/local/lib/R/site-library/testthat/include' -I'/tmp/RtmpPc0dLV/Rinsta1b2504ff/mockcpp/include' -I'/usr/local/lib/R/site-library/cpp11/include' -I/usr/local/include   -fpic  -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g  -c test-example.cpp -o test-example.o
    #>

       g++ -std=gnu++14 -I"/usr/local/lib/R/include" -DNDEBUG  -I'/usr/local/lib/R/site-library/testthat/include' -I'/tmp/RtmpPc0dLV/Rinsta1b2504ff/mockcpp/include' -I'/usr/local/lib/R/site-library/cpp11/include' -I/usr/local/include   -fpic  -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g  -c test-runner.cpp -o test-runner.o
    #>

       g++ -std=gnu++14 -shared -L/usr/local/lib/R/lib -L/usr/local/lib -o testcpp11.so test-example.o test-runner.o -L/usr/local/lib/R/lib -lR
    #>

       installing to /tmp/RtmptcByDM/devtools_install_641a368b70/00LOCK-testcpp11/00new/testcpp11/libs
    #>

       ** checking absolute paths in shared objects and dynamic libraries
    #>

    ─  DONE (testcpp11)
    #>

    # run the test
    testthat::test_file(
      system.file(
        'testcpp11/tests/testthat/test-cpp.R',
        package = 'mockcpp',
        mustWork = TRUE
      )
    )
    #>
    #> ══ Testing test-cpp.R ══════════════════════════════════════════════════════════
    #>
    [ FAIL 0 | WARN 0 | SKIP 0 | PASS 0 ]
    [ FAIL 0 | WARN 0 | SKIP 0 | PASS 0 ]
    [ FAIL 0 | WARN 0 | SKIP 0 | PASS 1 ] Done!