#' @param N number of repetitions for random regression tests regtest.bit <- function(N = 50) { OK <- TRUE pool <- c(FALSE, TRUE) if (!identical(unattr(as.bit(c(FALSE, NA, TRUE))[]), c(FALSE, FALSE, TRUE))) { message("bit error: wrong coercion of triboolean to (bi)boolean") OK <- FALSE } l <- TRUE b <- as.bit(l) i <- -c(1, 0, 1, NA) if (!inherits(try(b[i], silent=TRUE), "try-error")) { message("bit error: did not throw on mixing zero with negative subscripts") OK <- FALSE } i <- c(2, 1, 0, 1, NA) if (!identical(l[i], unattr(b[i]))) { message("\nregression test difference between b[i] and l[i]") message(l[i]) message(unattr(b[i])) OK <- FALSE } l[0] <- TRUE b[0] <- TRUE if (!identical(l, unattr(b[]))) { message("\nregression test difference after assigning at R position zero") message(l) message(unattr(b[])) OK <- FALSE } l[2] <- TRUE b[2] <- TRUE if (!identical(ifelse(is.na(l), FALSE, l), unattr(b[]))) { message("\nregression test difference after assigning after vector length (at 2)") message(l) message(unattr(b[])) OK <- FALSE } l[.BITS + 1] <- FALSE b[.BITS + 1] <- NA if (!identical(ifelse(is.na(l), FALSE, l), unattr(b[]))) { message("\nregression test difference after assigning after vector length (at .BITS + 1)") message(l) message(unattr(b[])) OK <- FALSE } if (!identical(ifelse(is.na(l[TRUE]), FALSE, l[TRUE]), unattr(b[TRUE]))) { message("\nregression test difference after subscripting with scalar TRUE") message(l) message(unattr(b[])) OK <- FALSE } if (!identical(ifelse(is.na(l[FALSE]), FALSE, l[FALSE]), unattr(b[FALSE]))) { message("\nregression test difference after subscripting with scalar FALSE") message(l) message(unattr(b[])) OK <- FALSE } for (i in 1:N) { n <- sample(1:(2 * .BITS), 1) l <- sample(pool, n, TRUE) # check direct coercion b <- as.bit(l) l2 <- as.logical(b) if (!identical(l, l2)) { message("\nregression test difference between logical") message(l) message("and as.logical(as.bit(logical))") message(l2) OK <- FALSE } # summary functions with logical return s <- c(all=all(l), any=any(l)) s2 <- c(all=all(b), any=any(b)) if (!identical(s, s2)) { message("\nregression test difference between logical summaries") message(s) message("and bit summaries") message(s2) OK <- FALSE } # summary functions with integer return if (any(l)) { s <- c( min=min(as.which(l)), max=max(as.which(l)), range=range(as.which(l)), sum=sum(l), summary=c( `FALSE`=length(l) - sum(l), `TRUE`=sum(l), Min.=min(as.which(l)), Max.=max(as.which(l)) ) ) } else { s <- c( min=NA_integer_, max=NA_integer_, range=c(NA_integer_, NA_integer_), sum=sum(l), summary=c( `FALSE`=length(l) - sum(l), `TRUE`=sum(l), Min.=NA_integer_, Max.=NA_integer_ ) ) } s2 <- c(min=min(b), max=max(b), range=range(b), sum=sum(b), summary=summary(b)) if (!identical(s, s2)) { message("\nregression test difference between logical summaries") message(s) message("and bit summaries") message(s2) OK <- FALSE } # check positive whichs w <- as.which(l) w2 <- as.which(as.bit(w, n)) if (!identical(w, w2)) { message("\nregression test difference between which") message(w) message("and as.which(as.bit.which(which))") message(w2) OK <- FALSE } # check automatic whichs (pos or neg whatever shorter) s <- sum(l) if (s == 0) { w <- FALSE } else if (s == n) { w <- TRUE } else if (s > n %/% 2L) { w <- -rev(which(!l)) } else { w <- which(l) } w2 <- as.vector(as.bitwhich(as.bit(l))) if (!identical(w, w2)) { message("\nregression test difference between which") message(w) message("and as.which(as.bit.which(which))") message(w2) OK <- FALSE } # check boolean operators l2 <- sample(c(FALSE, TRUE), n, TRUE) b2 <- as.bit(l2) ops <- c( NOT = identical(!l, as.logical(!b)) , AND = identical(l & l2, as.logical(b & b2)) , OR = identical(l | l2, as.logical(b | b2)) , XOR = identical(xor(l, l2), as.logical(xor(b, b2))) , NEQ = identical(l != l2, as.logical(b != b2)) , EQ = identical(l == l2, as.logical(b == b2)) ) if (!all(ops)) { message("\nbit differs for boolean operators(s)") message(ops) message(cbind(l=l, l2=l)) OK <- FALSE } w <- as.bitwhich(l) w2 <- as.bitwhich(l2) ops <- c( NOT = identical(!l, as.logical(!w)) , AND = identical(l & l2, as.logical(w & w2)) , OR = identical(l | l2, as.logical(w | w2)) , XOR = identical(xor(l, l2), as.logical(xor(w, w2))) , NEQ = identical(l != l2, as.logical(w != w2)) , EQ = identical(l == l2, as.logical(w == w2)) ) if (!all(ops)) { message("\nbitwhich differs for boolean operators(s)") message(ops) message(cbind(l=l, l2=l)) OK <- FALSE } rm(l2, b2, w2) # check extractors n2 <- sample(1:n, 1) j <- sample(1:n, n2) if (!identical(l[j], unattr(b[j]))) { message("\nregression test difference when extracting") OK <- FALSE } # check replacement (index) new_value <- sample(pool, n2, TRUE) l[j] <- new_value b[j] <- new_value if (!identical(l, unattr(b[]))) { message("\nregression test difference when replacing with index") OK <- FALSE } # check replacement (recycle) if (n %% 2) { new_value <- sample(pool, 1) l[] <- new_value b[] <- new_value } else { l[] <- pool b[] <- pool } if (!identical(l, as.logical(b))) { message("\nregression test difference when replacing with recylcling") OK <- FALSE } } l0 <- c(FALSE, FALSE, FALSE) l1 <- c(FALSE, FALSE, TRUE) l2 <- c(FALSE, TRUE, TRUE) l3 <- c(TRUE, TRUE, TRUE) bw0 <- as.bitwhich(l0) bw1 <- as.bitwhich(l1) bw2 <- as.bitwhich(l2) bw3 <- as.bitwhich(l3) OK <- OK && identical(l0, as.logical(bw0)) OK <- OK && identical(l1, as.logical(bw1)) OK <- OK && identical(l2, as.logical(bw2)) OK <- OK && identical(l3, as.logical(bw3)) OK <- OK && identical(l0 & l0, as.logical(bw0 & bw0)) OK <- OK && identical(l0 & l1, as.logical(bw0 & bw1)) OK <- OK && identical(l0 & l2, as.logical(bw0 & bw2)) OK <- OK && identical(l0 & l3, as.logical(bw0 & bw3)) OK <- OK && identical(l1 & l0, as.logical(bw1 & bw0)) OK <- OK && identical(l1 & l1, as.logical(bw1 & bw1)) OK <- OK && identical(l1 & l2, as.logical(bw1 & bw2)) OK <- OK && identical(l1 & l3, as.logical(bw1 & bw3)) OK <- OK && identical(l2 & l0, as.logical(bw2 & bw0)) OK <- OK && identical(l2 & l1, as.logical(bw2 & bw1)) OK <- OK && identical(l2 & l2, as.logical(bw2 & bw2)) OK <- OK && identical(l2 & l3, as.logical(bw2 & bw3)) OK <- OK && identical(l3 & l0, as.logical(bw3 & bw0)) OK <- OK && identical(l3 & l1, as.logical(bw3 & bw1)) OK <- OK && identical(l3 & l2, as.logical(bw3 & bw2)) OK <- OK && identical(l3 & l3, as.logical(bw3 & bw3)) OK <- OK && identical(l0 | l0, as.logical(bw0 | bw0)) OK <- OK && identical(l0 | l1, as.logical(bw0 | bw1)) OK <- OK && identical(l0 | l2, as.logical(bw0 | bw2)) OK <- OK && identical(l0 | l3, as.logical(bw0 | bw3)) OK <- OK && identical(l1 | l0, as.logical(bw1 | bw0)) OK <- OK && identical(l1 | l1, as.logical(bw1 | bw1)) OK <- OK && identical(l1 | l2, as.logical(bw1 | bw2)) OK <- OK && identical(l1 | l3, as.logical(bw1 | bw3)) OK <- OK && identical(l2 | l0, as.logical(bw2 | bw0)) OK <- OK && identical(l2 | l1, as.logical(bw2 | bw1)) OK <- OK && identical(l2 | l2, as.logical(bw2 | bw2)) OK <- OK && identical(l2 | l3, as.logical(bw2 | bw3)) OK <- OK && identical(l3 | l0, as.logical(bw3 | bw0)) OK <- OK && identical(l3 | l1, as.logical(bw3 | bw1)) OK <- OK && identical(l3 | l2, as.logical(bw3 | bw2)) OK <- OK && identical(l3 | l3, as.logical(bw3 | bw3)) OK <- OK && identical(xor(l0, l0), as.logical(xor(bw0, bw0))) OK <- OK && identical(xor(l0, l1), as.logical(xor(bw0, bw1))) OK <- OK && identical(xor(l0, l2), as.logical(xor(bw0, bw2))) OK <- OK && identical(xor(l0, l3), as.logical(xor(bw0, bw3))) OK <- OK && identical(xor(l1, l0), as.logical(xor(bw1, bw0))) OK <- OK && identical(xor(l1, l1), as.logical(xor(bw1, bw1))) OK <- OK && identical(xor(l1, l2), as.logical(xor(bw1, bw2))) OK <- OK && identical(xor(l1, l3), as.logical(xor(bw1, bw3))) OK <- OK && identical(xor(l2, l0), as.logical(xor(bw2, bw0))) OK <- OK && identical(xor(l2, l1), as.logical(xor(bw2, bw1))) OK <- OK && identical(xor(l2, l2), as.logical(xor(bw2, bw2))) OK <- OK && identical(xor(l2, l3), as.logical(xor(bw2, bw3))) OK <- OK && identical(xor(l3, l0), as.logical(xor(bw3, bw0))) OK <- OK && identical(xor(l3, l1), as.logical(xor(bw3, bw1))) OK <- OK && identical(xor(l3, l2), as.logical(xor(bw3, bw2))) OK <- OK && identical(xor(l3, l3), as.logical(xor(bw3, bw3))) OK <- OK && identical(c(l0, l0), as.logical(c(bw0, bw0))) OK <- OK && identical(c(l0, l1), as.logical(c(bw0, bw1))) OK <- OK && identical(c(l0, l2), as.logical(c(bw0, bw2))) OK <- OK && identical(c(l0, l3), as.logical(c(bw0, bw3))) OK <- OK && identical(c(l1, l0), as.logical(c(bw1, bw0))) OK <- OK && identical(c(l1, l1), as.logical(c(bw1, bw1))) OK <- OK && identical(c(l1, l2), as.logical(c(bw1, bw2))) OK <- OK && identical(c(l1, l3), as.logical(c(bw1, bw3))) OK <- OK && identical(c(l2, l0), as.logical(c(bw2, bw0))) OK <- OK && identical(c(l2, l1), as.logical(c(bw2, bw1))) OK <- OK && identical(c(l2, l2), as.logical(c(bw2, bw2))) OK <- OK && identical(c(l2, l3), as.logical(c(bw2, bw3))) OK <- OK && identical(c(l3, l0), as.logical(c(bw3, bw0))) OK <- OK && identical(c(l3, l1), as.logical(c(bw3, bw1))) OK <- OK && identical(c(l3, l2), as.logical(c(bw3, bw2))) OK <- OK && identical(c(l3, l3), as.logical(c(bw3, bw3))) N <- 2L * .BITS l <- logical(N) b <- bit(N) for (i in 1:N) { l[i] <- TRUE b[i] <- TRUE if (!identical(l, as.logical(b))) { message("\nregression test difference when replacing at position", i, "") OK <- FALSE } } OK } test_that("old regtest is still OK", { expect_true(regtest.bit()) }) test_that("some old regression tests are also OK for bitwhich", { expect_error(TRUE[c(-1, 1)], label="positive mixed with zeros") expect_error(as.bit(TRUE)[c(-1, 1)], label="positive mixed with zeros") expect_error(as.bitwhich(TRUE)[c(-1, 1)], label="positive mixed with zeros") expect_error(TRUE[c(-1, NA)], label="NA mixed with zeros") expect_error(as.bit(TRUE)[c(-1, NA)], label="NA mixed with zeros") expect_error(as.bitwhich(TRUE)[c(-1, NA)], label="NA mixed with zeros") expect_identical( as.bit(TRUE)[c(2, 1, 0, 1, NA)], TRUE[c(2, 1, 0, 1, NA)], ignore_attr="vmode" ) expect_identical( as.bitwhich(TRUE)[c(2, 1, 0, 1, NA)], TRUE[c(2, 1, 0, 1, NA)], ignore_attr="vmode" ) l = FALSE l[0L] = TRUE b = as.bit(FALSE) b[0L] = TRUE expect_identical(as.logical(b), l) w = as.bitwhich(FALSE) w[0L] = TRUE expect_identical(as.logical(w), l) l = FALSE l[2L] = TRUE b = as.bit(FALSE) b[2L] = TRUE expect_identical(as.logical(b), l) w = as.bitwhich(FALSE) w[2L] = TRUE expect_identical(as.logical(w), l) l = FALSE l[.BITS + 1L] = FALSE l[is.na(l)] = FALSE b = as.bit(FALSE) b[.BITS + 1L] = NA expect_identical(as.logical(b), l) w = as.bitwhich(FALSE) w[.BITS + 1L] = NA expect_identical(as.logical(w), l) expect_identical( as.bit(rep(c(FALSE, TRUE), .BITS))[TRUE], rep(c(FALSE, TRUE), .BITS)[TRUE], ignore_attr="vmode", label="subscripting with scalar TRUE" ) expect_identical( as.bitwhich(rep(c(FALSE, TRUE), .BITS))[TRUE], rep(c(FALSE, TRUE), .BITS)[TRUE], ignore_attr="vmode", label="subscripting with scalar TRUE" ) expect_identical( as.bit(rep(c(FALSE, TRUE), .BITS))[FALSE], rep(c(FALSE, TRUE), .BITS)[FALSE], ignore_attr="vmode", label="subscripting with scalar FALSE" ) expect_identical( as.bitwhich(rep(c(FALSE, TRUE), .BITS))[FALSE], rep(c(FALSE, TRUE), .BITS)[FALSE], ignore_attr="vmode", label="subscripting with scalar FALSE" ) })