[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/josh28x/cpp11/main/cpp11test/src/test-strings.cpp [Back]  [Original]

#include 
#include "cpp11/sexp.hpp"
#include "cpp11/strings.hpp"

#include 

context("strings-C++") {
  test_that("strings.push_back()") {
    cpp11::writable::strings x;
    x.push_back("a");
    x.push_back("b");

    expect_true(x.size() == 2);
    expect_true(x[0] == "a");
    expect_true(x[1] == "b");
  }
  test_that("strings.resize()") {
    cpp11::writable::strings x;
    x.resize(2);
    x[0] = "a";
    x[1] = "b";

    expect_true(x.size() == 2);
    expect_true(x[0] == "a");
    expect_true(x[1] == "b");
  }
  test_that("strings.at()") {
    cpp11::writable::strings x;

    expect_error(x.at(-1));

    expect_error(x.at(0));

    x.push_back("a");
    auto test = x.at(0);
    expect_true(test == "a");
    expect_error(x.at(1));
  }
  test_that("strings.pop_back()") {
    cpp11::writable::strings x;

    x.push_back("a");
    x.push_back("b");
    x.pop_back();

    expect_true(x.size() == 1);
    expect_true(x[0] == "a");

    expect_error(x.at(1));
  }
  test_that("strings.insert()") {
    cpp11::writable::strings x;

    x.insert(0, "a");
    x.insert(0, "b");
    x.insert(1, "c");
    expect_true(x.size() == 3);

    expect_true(x[0] == "b");
    expect_true(x[1] == "c");
    expect_true(x[2] == "a");
  }

  test_that("strings.erase()") {
    cpp11::writable::strings x;

    x.push_back("a");
    x.push_back("b");
    x.push_back("c");
    x.push_back("d");
    x.push_back("e");

    expect_true(x.size() == 5);

    x.erase(0);

    expect_true(x.size() == 4);
    expect_true(x[0] == "b");
    expect_true(x[1] == "c");
    expect_true(x[2] == "d");
    expect_true(x[3] == "e");

    x.erase(2);

    expect_true(x.size() == 3);
    expect_true(x[0] == "b");
    expect_true(x[1] == "c");
    expect_true(x[2] == "e");
  }

  test_that("strings.iterator* = ") {
    cpp11::writable::strings x;
    x.push_back("a");
    x.push_back("b");
    x.push_back("c");
    auto it = x.begin() + 1;
    *it = "d";
    ++it;
    *it = "e";

    expect_true(x.size() == 3);
    expect_true(x[0] == "a");
    expect_true(x[1] == "d");
    expect_true(x[2] == "e");
  }

  test_that("writable::strings(SEXP)") {
    SEXP x = PROTECT(Rf_allocVector(STRSXP, 5));

    SET_STRING_ELT(x, 0, Rf_mkCharCE("a", CE_UTF8));
    SET_STRING_ELT(x, 1, Rf_mkCharCE("b", CE_UTF8));
    SET_STRING_ELT(x, 2, Rf_mkCharCE("c", CE_UTF8));
    SET_STRING_ELT(x, 3, Rf_mkCharCE("d", CE_UTF8));
    SET_STRING_ELT(x, 4, Rf_mkCharCE("e", CE_UTF8));

    cpp11::writable::strings y(x);
    y[0] = "foo";

    expect_true(x != y.data());

    expect_true(std::string(CHAR(STRING_ELT(x, 0))) == "a");
    expect_true(y[0] == "foo");

    cpp11::writable::strings z(y);
    z[0] = "bar";

    expect_true(z.data() != y.data());

    expect_true(std::string(CHAR(STRING_ELT(x, 0))) == "a");
    expect_true(y[0] == "foo");
    expect_true(z[0] == "bar");

    UNPROTECT(1);
  }

  test_that("writable::strings(initializer_list)") {
    using namespace cpp11::literals;

    SEXP x1 = PROTECT(Rf_allocVector(STRSXP, 1));
    SEXP x2 = PROTECT(Rf_allocVector(STRSXP, 1));
    SEXP x3 = PROTECT(Rf_allocVector(STRSXP, 1));

    SEXP one = PROTECT(Rf_mkCharCE("one", CE_UTF8));
    SEXP two = PROTECT(Rf_mkCharCE("two", CE_UTF8));
    SEXP three = PROTECT(Rf_mkCharCE("three", CE_UTF8));

    SET_STRING_ELT(x1, 0, one);
    SET_STRING_ELT(x2, 0, two);
    SET_STRING_ELT(x3, 0, three);

    // From scalar string vectors
    cpp11::writable::strings x({"one"_nm = x1, "two"_nm = x2, "three"_nm = x3});
    expect_true(x.named());
    expect_true(x["one"] == cpp11::r_string("one"));
    expect_true(x["two"] == cpp11::r_string("two"));
    expect_true(x["three"] == cpp11::r_string("three"));

    // From strings
    cpp11::writable::strings y(
        {"one"_nm = "one", "two"_nm = "two", "three"_nm = "three"});
    expect_true(y.named());
    expect_true(y["one"] == cpp11::r_string("one"));
    expect_true(y["two"] == cpp11::r_string("two"));
    expect_true(y["three"] == cpp11::r_string("three"));

    UNPROTECT(6);
  }

  test_that("writable::strings(initializer_list) type check") {
    using namespace cpp11::literals;
    expect_error_as(cpp11::writable::strings({"one"_nm = true}), cpp11::type_error);
    expect_error_as(cpp11::writable::strings({"one"_nm = R_NilValue}), cpp11::type_error);
  }

  test_that("writable::strings(initializer_list) length check") {
    using namespace cpp11::literals;
    SEXP x = PROTECT(Rf_allocVector(STRSXP, 2));
    expect_error_as(cpp11::writable::strings({"x"_nm = x}), std::length_error);
    UNPROTECT(1);
  }

  test_that("writable::strings(initializer_list)") {
    cpp11::r_string abc = cpp11::r_string("abc");
    cpp11::r_string na = cpp11::r_string(NA_STRING);

    cpp11::writable::strings x({abc, na, abc});
    expect_true(x[0] == abc);
    expect_true(x[1] == na);
    expect_true(x[2] == abc);

    // This works due to implicit conversion of `SEXP` to `r_string`
    SEXP a = PROTECT(Rf_mkCharCE("a", CE_UTF8));
    SEXP b = PROTECT(Rf_mkCharCE("b", CE_UTF8));
    cpp11::writable::strings y({a, b});
    expect_true(y[0] == cpp11::r_string("a"));
    expect_true(y[1] == cpp11::r_string("b"));

    // This works due to implicit conversion of `const char*` to `r_string`
    cpp11::writable::strings z({"neat", "stuff"});
    expect_true(z[0] == cpp11::r_string("neat"));
    expect_true(z[1] == cpp11::r_string("stuff"));

    cpp11::writable::strings w({std::string("neat"), std::string("stuff")});
    expect_true(w[0] == cpp11::r_string("neat"));
    expect_true(w[1] == cpp11::r_string("stuff"));

    UNPROTECT(2);
  }

  test_that("std::initializer_list") {
    cpp11::writable::strings x{"foo"};
    expect_true(x.size() == 1);
    expect_true(x[0] == "foo");
  }

  test_that("std::initializer_list") {
    std::string str("foo");
    cpp11::writable::strings x{str};
    expect_true(x.size() == 1);
    expect_true(x[0] == "foo");
  }

  test_that("NA_STRING constructor") {
    cpp11::writable::strings x({NA_STRING});

    expect_true(x.size() == 1);
    expect_true(x[0] == NA_STRING);

    cpp11::writable::strings y({NA_STRING, "foo"});

    expect_true(y.size() == 2);
    expect_true(y[0] == NA_STRING);
    expect_true(y[1] == "foo");
  }

  test_that("CHARSXP move constructor") {
    SEXP x = PROTECT(Rf_mkChar("foo"));
    cpp11::writable::strings y(std::move(x));

    expect_true(y.size() == 1);
    expect_true(y[0] == "foo");
    UNPROTECT(1);
  }

  // test_that("strings::operator=() and strings::at() do not compile") {
  // cpp11::strings x(Rf_mkChar("foo"));

  // x[0] = "bar";
  // x.at(0) = "bar";
  //}

  test_that("strings::operator=() and strings::at() do compile") {
    cpp11::writable::strings x(Rf_mkChar("foo"));

    x[0] = "bar";
    x.at(0) = "bar";
  }

  test_that("strings::operator=() works with std:strings") {
    cpp11::writable::strings x(Rf_mkChar("foo"));
    std::string y("bar");

    x[0] = y;
    expect_true(x[0] == y);
  }

  test_that("conversion to SEXP with missing values") {
    cpp11::sexp x1 = cpp11::r_string(NA_STRING);
    expect_true(static_cast(x1) == NA_STRING);

    cpp11::sexp x2 = cpp11::writable::strings(NA_STRING);
    expect_true(Rf_xlength(x2) == 1);
    expect_true(STRING_ELT(x2, 0) == NA_STRING);

    cpp11::sexp x3 = cpp11::writable::strings({NA_STRING});
    expect_true(Rf_xlength(x3) == 1);
    expect_true(STRING_ELT(x3, 0) == NA_STRING);

    cpp11::sexp x4 = cpp11::writable::strings({NA_STRING, "text"});
    expect_true(Rf_xlength(x4) == 2);
    expect_true(STRING_ELT(x4, 0) == NA_STRING);
    expect_true(strcmp(CHAR(STRING_ELT(x4, 1)), "text") == 0);
  }
}

Web Proxy Viewer  |  New URL  |  Original Page