Skip to content

Commit 8214ddc

Browse files
committed
Add test related to attribute retention
1 parent 6df9fb5 commit 8214ddc

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

cpp11test/src/test-r_vector.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,4 +325,47 @@ context("r_vector-C++") {
325325
expect_true(x.data() != R_NilValue);
326326
expect_true(x.size() == 3);
327327
}
328+
329+
test_that(
330+
"writable vector truncation resizes names and retains attributes (but not dim or "
331+
"dim names)") {
332+
cpp11::writable::integers x(2);
333+
x[0] = 1;
334+
x[1] = 2;
335+
336+
// Doubles the capacity from 2 to 4, meaning the underlying SEXP has length 4 now.
337+
x.push_back(3);
338+
expect_true(Rf_xlength(x.data()) == 4);
339+
340+
// Set some names
341+
SEXP names = PROTECT(Rf_allocVector(STRSXP, 3));
342+
SET_STRING_ELT(names, 0, Rf_mkCharCE("x", CE_UTF8));
343+
SET_STRING_ELT(names, 1, Rf_mkCharCE("y", CE_UTF8));
344+
SET_STRING_ELT(names, 2, Rf_mkCharCE("z", CE_UTF8));
345+
x.names() = names;
346+
347+
// Length of names SEXP is actually 4 now, extended by `setAttrib()` to match
348+
// the internal capacity
349+
expect_true(Rf_xlength(Rf_getAttrib(x.data(), R_NamesSymbol)) == 4);
350+
351+
// Set an attribute
352+
SEXP bar = PROTECT(Rf_ScalarInteger(1));
353+
x.attr("foo") = bar;
354+
355+
// Extract out the underlying SEXP using the operator:
356+
// - This truncates to size 3
357+
// - This truncates and keeps names
358+
// - This copies over attributes like `"foo"`
359+
// - This updates the internal SEXP in `x` to the one in `x_sexp` (gross but users
360+
// probably expect this at this point)
361+
SEXP x_sexp = x;
362+
363+
expect_true(Rf_xlength(x_sexp) == 3);
364+
expect_true(Rf_xlength(Rf_getAttrib(x_sexp, R_NamesSymbol)) == 3);
365+
expect_true(Rf_getAttrib(x_sexp, Rf_install("foo")) == bar);
366+
367+
expect_true(x.data() == x_sexp);
368+
369+
UNPROTECT(2);
370+
}
328371
}

0 commit comments

Comments
 (0)