# Copyright (C) Brodie Gaslam
#
# This file is part of "unitizer - Interactive R Unit Tests"
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Go to <https://www.r-project.org/Licenses/GPL-2> for a copy of the license.
# This used to have all the state comparison methods, but those just became
# unneeded with the advent of diffobj
#
# \code{all.equal} methods involving dummy
#' @rdname unitizer_s4method_doc
setMethod( # We could just drop this altogether, but leaving it for future use
"all.equal", c("unitizerDummy", "unitizerDummy"),
function(target, current, ...) TRUE
)
#' @rdname unitizer_s4method_doc
setMethod(
"all.equal", c("unitizerDummy", "ANY"),
function(target, current, ...)
paste(
"`.REF` value was not recorded, but `.NEW` value was; they are likely",
"different"
)
)
#' @rdname unitizer_s4method_doc
setMethod(
"all.equal", c("ANY", "unitizerDummy"),
function(target, current, ...)
paste(
"`.NEW` value was not recorded, but `.REF` value was; they are likely",
"different"
)
)
#' @export
#' @rdname unitizer_s4method_doc
setMethod("all.equal", c("unitizerStateRaw", "unitizerStateRaw"),
function(target, current, ...) {
for(i in slotNames(target)) {
if(!isTRUE(diff <- all.equal(slot(target, i), slot(current, i))))
return(sprintf("Slot `%s` is not all equal: %s", i, diff))
}
TRUE
}
)
# To force recognizing the S4 method when called from inside another package
# which happens when we're doing `in_pkg`; will only work if the first argument
# is `unitizerDummy`, which should be the most common use case
#' @export
all.equal.unitizerDummy <- function(target, current, ...) {
all.equal(target, current, ...)
}
#' @export
all.equal.unitizerStateRaw <- function(target, current, ...) {
all.equal(target, current, ...)
}
# specifically an all.equal that returns garbage for testing; unfortunately
# this needs to be exported to be useable (blergh) (IS THIS STILL USED?)
# nocov start
#' @export
all.equal.unitizer_glob_state_test <- function(target, current, ...)
list(1, 2, list("woohoo"))
# nocov end
## Merge State Data Between Reference and New Indices
##
## Required because we track these separately, but when we merge new and
## reference items we have to account for states from both.
##
## The items will be what is created by the review process and will contain a
## mix of new and reference items. We go through and identify the reference
## items, and pull out the relevant states from the ref states tracking store
## and append them to the new states. As part of this process, we need to
## re-index all the reference state elements to start counting after the end of
## the new state elements.
##
## @param x items, typically "reference" item being prepared for storage
## @param y new states
## @param z ref states
setGeneric("mergeStates", function(x, y, z, ...) standardGeneric("mergeStates"))
setMethod(
"mergeStates", c(
"unitizerItems", "unitizerGlobalTrackingStore",
"unitizerGlobalTrackingStore"
),
function(x, y, z, ...) {
types <- itemsType(x)
types.ref <- which(types == "reference")
if(length(types.ref)) {
ref.indices <- lapply(x[types.ref], slot, "glob.indices")
max.indices <- unitizerStateMaxIndices(y) # max new index
# Map the global indices in reference to values starting from 1 up beyond
# the end of the indices in the new indices, though use zeros for zero;
# these are the index location for the reference items once we append
# them to the tracking object; use `do.call` because `vapply`/`apply`
# unstable in 1 column vs multi column inputs (#212, #199)
remap <- function(w)
match(w, sort(Filter(as.logical, unique(w))), nomatch=0L)
ref.ind.mx <- do.call(cbind, lapply(ref.indices, as.integer))
ref.ind.mx.map <- do.call(
rbind, lapply(split(ref.ind.mx, row(ref.ind.mx)), remap)
) + as.integer(max.indices)
rownames(ref.ind.mx.map) <- rownames(ref.ind.mx)
if(!identical(attributes(ref.ind.mx), attributes(ref.ind.mx.map))) {
stop( # nocov start
"Internal Error: global index mapping matrix malformed; contact ",
"maintainer."
) # nocov end
}
ref.ind.mx.map[!ref.ind.mx] <- 0L # these all map to the starting state
# Pull out the states from ref and copy them into new; note that it is
# possible for reference states to all reference the 0 index, meaning a
# state wasn't captured, in that case we don't do anything
for(i in slotNames(y)) {
needed.state.ids <- unique(ref.ind.mx[i, ])
needed.state.ids.map <- unique(ref.ind.mx.map[i, ])
max.map.id <- max(needed.state.ids.map)
if(max.map.id) { # 0 index only
length(slot(y, i)) <- max.map.id
for(j in seq_along(needed.state.ids)) {
id <- needed.state.ids[[j]]
id.map <- needed.state.ids.map[[j]]
if(!id.map) next
slot(y, i)[[id.map]] <- slot(z, i)[[id]]
}
}
}
# For each ref index, remap to the new positions in new state
for(i in seq_along(types.ref)) {
old.id <- types.ref[[i]]
x[[old.id]]@glob.indices <- do.call(
"new", c(list("unitizerGlobalIndices"), as.list(ref.ind.mx.map[, i]))
) } }
# Return a list with the update item list and the states
list(items=x, states=y)
} )
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.