#' expect_equal_workbooks() ------------------------------------------
#' Quick internal expectation function. Easier to ignore fields to be set
expect_equal_workbooks <- function(object, expected, ..., ignore_fields = NULL) {
# object <- as.list(object)
# expected <- as.list(expected)
requireNamespace("waldo")
assert_workbook(object)
assert_workbook(expected)
fields <- c(names(wbWorkbook$public_fields), names(wbWorkbook$private_fields))
bad <- setdiff(ignore_fields, fields)
if (length(bad)) {
stop("Invalid fields: ", toString(bad))
}
for (i in ignore_fields) {
object[[i]] <- NULL
expected[[i]] <- NULL
}
bad <- waldo::compare(
x = object,
y = expected,
x_arg = "object",
y_arg = "expected",
...
)
if (length(bad)) {
testthat::fail(bad)
return(invisible())
}
testthat::succeed()
return(invisible())
}
# expect_wrapper helper --------------------
#' Expect wrapper
#'
#' Internal tool: see tests/testthat/test-workbook-wrappers.R
#'
#' @description Testing expectations for [wbWorkbook] wrappers. These test that
#' the method and wrappers have the same params, same default values, and
#' return the same value.
#'
#' Requires the `waldo` package, used within `testthat`.
#'
#' @param method The name of the [wbWorkbook] method
#' @param fun The name of the wrapper (probably in R/class-workbook-wrappers)
#' @param wb A `wbWorkbook` object
#' @param params A named list of params. Set to `NULL` to not execute functions
#' @param ignore Names of params to ignore
#' @param ignore_attr Passed to `waldo::compare()` for the result of the
#' executed functions
#' @param ignore_fields Ignore immediate fields by removing them from the
#' objects for comparison
#' @param ignore_wb for pseudo wbWorkbook wrappers such as wb_load() we have
#' to ignore wb
#' @returns Nothing, called for its side-effects
expect_wrapper <- function(
method,
fun = paste0("wb_", method),
wb = wb_workbook(),
params = list(),
ignore = NULL,
ignore_attr = "waldo_opts",
ignore_fields = NULL,
ignore_wb = FALSE
) {
stopifnot(
requireNamespace("waldo", quietly = TRUE),
is.character(method), length(method) == 1L,
is.character(fun), length(fun) == 1L,
is.list(params) || is.null(params)
)
method_fun <- get(method, wbWorkbook$public_methods)
fun_fun <- match.fun(fun)
# these come as pairlist -- we don't really care about that
method_forms <- as.list(formals(method_fun))
fun_forms <- as.list(formals(fun_fun))
method_args <- names(method_forms)
fun_args <- names(fun_forms)
# remove wb and other ignores
ignore <- c("wb", ignore)
# remove ignores from fun
m <- match(ignore, fun_args, 0L)
if (!identical(m, 0L)) {
# remove wb from both the args and formals
fun_args <- fun_args[-m]
fun_forms <- fun_forms[-m]
}
# remove ignores from method
m <- match(ignore, method_args, 0L)
if (!identical(m, 0L)) {
# remove wb from both the args and formals
method_args <- method_args[-m]
method_forms <- method_forms[-m]
}
method0 <- paste0("wbWorkbook$", method)
# adjustments for when wrappers don't have any args
if (!length(method_args)) {
method_args <- character()
}
if (!length(method_forms)) {
method_forms <- structure(list(), names = character())
}
# expectation that the names are the same (possibly redundant but quicker to)
bad <- waldo::compare(
x = method_args,
y = setdiff(fun_args, "wb"),
x_arg = method0,
y_arg = fun
)
if (length(bad)) {
testthat::fail(bad)
return(invisible())
}
# expectation that the default values are the same
bad <- waldo::compare(
x = method_forms,
y = fun_forms,
x_arg = method0,
y_arg = fun
)
if (length(bad)) {
testthat::fail(bad)
return(invisible())
}
if (!is.null(params)) {
# create now so that it's the same every time
wb_fun <- wb$clone(deep = TRUE)
wb_method <- wb$clone(deep = TRUE)
# be careful and report when we failed to run these
# the style names are generated at random: use matching seeds for both calls
options("openxlsx2_seed" = NULL)
if (ignore_wb) {
res_fun <- try(do.call(fun, c(params)), silent = TRUE)
} else {
res_fun <- try(do.call(fun, c(wb = wb_fun, params)), silent = TRUE)
}
options("openxlsx2_seed" = NULL)
res_method <- try(do.call(wb_method[[method]], params), silent = TRUE)
msg <- NULL
if (inherits(res_fun, "try-error")) {
temp <- file()
writeLines(attr(res_fun, "condition")$message, temp)
bad <- paste0("# > ", readLines(temp))
close(temp)
expr <- paste0("\n", deparse1(do.call(call, c(fun, c(wb = wb_fun, params)))))
msg <- c(msg, expr, bad)
}
if (inherits(res_method, "try-error")) {
temp <- file()
writeLines(attr(res_method, "condition")$message, temp)
bad <- paste0("# > ", readLines(temp))
close(temp)
expr <- paste0("\n", deparse1(do.call(call, c(method0, params))))
# slight fix because we get those "`" which I don't want to see
expr <- sub(paste0("`", method0, "`"), method0, expr, fixed = TRUE)
msg <- c(msg, expr, bad)
}
if (!is.null(msg)) {
# browser()
bad <- c("Failed to get results", msg)
testthat::fail(bad)
return(invisible())
}
for (i in ignore_fields) {
# remove the fields we don't want to check
res_method[[i]] <- NULL
res_fun[[i]] <- NULL
}
# expectation that the results are the same
bad <- waldo::compare(
x = res_method,
y = res_fun,
x_arg = method0,
y_arg = fun,
ignore_attr = ignore_attr,
ignore_formula_env = TRUE
)
if (length(bad)) {
testthat::fail(bad)
return(invisible())
}
}
testthat::succeed()
return(invisible())
}
# `expect_pseudo_wrapper()` -------
#' A trimmed down pseudo wrapper to check internal wrapped functions.
#' @rdname expect_wrapper
expect_pseudo_wrapper <- function(
method,
fun = paste0("wb_", method)
) {
method_fun <- get(method, wbWorkbook$public_methods)
fun_fun <- match.fun(fun)
method_forms <- as.list(formals(method_fun))
fun_forms <- as.list(formals(fun_fun))
method_args <- names(method_forms)
fun_args <- names(fun_forms)
ignore <- "file"
# remove ignores from fun
m <- match(ignore, fun_args, 0L)
if (!identical(m, 0L)) {
# remove wb from both the args and formals
fun_args <- fun_args[-m]
fun_forms <- fun_forms[-m]
}
# remove ignores from method
m <- match(ignore, method_args, 0L)
if (!identical(m, 0L)) {
# remove wb from both the args and formals
method_args <- method_args[-m]
method_forms <- method_forms[-m]
}
# expectation that the names are the same (possibly redundant but quicker to)
bad <- waldo::compare(
x = method_args,
y = setdiff(fun_args, "wb")
)
if (length(bad)) {
testthat::fail(bad)
return(invisible())
}
# expectation that the default values are the same
bad <- waldo::compare(
x = method_forms,
y = fun_forms
)
if (length(bad)) {
testthat::fail(bad)
return(invisible())
}
testthat::succeed()
return(invisible())
}
# Miscellaneous helpers for testthat -----------
expected_shared_strings <- function() {
structure(c(
"v1", "v2", "v3",
"v4", "v5", "v6",
"v7", "v8", "v9",
"bool", "Date", "value",
"word", "N-Z-P-S-Y", "C-G-D-X-H",
"B-K-A-O-W", "H-P-G-O-K", "F-P-C-L-T",
"A-N-Q-P-V", "Y-E-B-K-O", "V-S-N-T-R",
"F-K-Z-U-S", "O-E-Z-T-G", "Q-X-F-L-N",
"E-D-Y-Z-N", "W-F-L-C-I", "P-S-W-Y-E",
"P-H-N-Q-Z", "S-O-L-W-J", "J-E-F-Q-K",
"D-N-O-P-Z", "H-Z-K-S-U", "B-P-A-Y-R",
"Z-I-X-J-V", "Y-S-I-M-X", "V-A-C-R-O",
"O-V-S-C-Q", "A-K-S-V-W", "B-G-U-S-J",
"Z-E-J-V-T", "P-F-C-N-T", "L-T-Z-D-V",
"K-Q-Y-N-O", "U-S-Z-O-E", "Y-F-Z-C-P",
"P-Y-M-I-K", "D-Y-A-L-T", "W-I-F-A-B",
"I-H-S-W-K", "U-D-J-F-K", "B-K-G-J-V",
"Y-J-E-N-B", "X-L-V-S-U", "A-I-B-S-P",
"U-L-D-O-M", "M-D-V-R-X", "O-Q-K-S-B",
"O-R-X-C-W", "O-F-M-A-X", "J-K-V-E-X",
"W-B-S-O-A", "R-N-D-G-S", "W-J-K-M-R",
"K-I-H-F-M", "U-F-X-P-A", "M-R-C-H-L",
"H-A-E-X-J", "C-B-K-L-S", "V-A-I-S-L",
"B-L-N-J-G", "J-X-A-D-O", "I-S-W-P-U",
"D-R-M-G-C", "M-V-U-D-W", "U-S-A-Z-B",
"T-E-N-F-P", "K-E-S-Z-Y", "D-J-O-T-A",
"F-U-Y-T-R", "Q-U-N-P-J", "D-C-V-A-X",
"S-B-F-E-V", "U-R-P-H-A", "R-C-Z-J-B",
"L-B-M-F-I", "D-Y-B-S-Q", "X-Y-D-W-P",
"Z-L-I-V-R", "Z-W-T-M-B", "Z-U-S-E-G",
"V-I-M-C-O", "E-K-D-R-Z", "Z-F-H-Y-D",
"O-I-X-M-A", "F-K-U-G-T", "I-P-X-J-M",
"F-N-Z-E-C", "F-A-M-X-E", "R-V-C-O-P",
"X-Y-C-V-H", "K-G-T-Y-I", "N-M-E-D-F",
"M-K-N-U-W", "L-K-J-A-B", "S-M-T-D-A",
"W-D-G-F-U", "X-R-Z-F-E", "H-L-N-G-P",
"Z-X-W-M-R", "E-F-G-J-V", "X-I-M-Z-V",
"T-A-O-L-Q", "F-T-X-N-B", "O-G-D-P-A",
"B-K-Z-V-M", "M-J-O-S-X", "O-D-M-S-G",
"W-O-V-A-D", "I-D-W-T-H", "E-C-I-A-L",
"P-I-W-U-T", "Y-P-U-L-C", "Q-N-A-B-E",
"C-F-X-Y-H", "Q-P-G-I-J", "A-Q-J-W-F",
"G-N-R-U-D", "G-L-I-F-V", "Y-R-P-K-X",
"V-W-B-G-S", "E-Q-D-N-F", "E-R-U-D-O",
"O-E-G-X-L", "D-Q-G-A-K", "U-Z-N-C-V",
"O-K-T-W-X", "L-W-G-K-Q", "I-F-O-X-Q",
"J-B-V-W-T", "U-H-I-P-Q", "R-W-M-S-U",
"F-U-M-W-H", "F-A-Q-U-K", "Q-R-D-K-I",
"L-P-K-V-S", "G-I-B-U-Q", "Z-W-L-G-E",
"Q-C-I-B-A", "J-N-Y-W-D", "T-Y-G-W-S",
"L-M-A-G-K", "O-D-S-T-K", "O-G-L-T-Z",
"N-Q-E-B-F", "B-F-W-A-X", "U-G-Q-B-M",
"B-O-V-U-A", "R-K-X-H-A", "B-P-Q-T-R",
"I-P-Z-L-V", "C-T-L-W-D", "L-Q-D-M-U",
"N-P-H-A-G", "F-O-P-G-M", "N-M-Z-W-L",
"G-V-K-Z-T", "F-J-T-C-U", "J-P-R-A-C",
"Z-X-V-C-W", "B-Z-K-I-Q", "E-N-L-I-Y",
"C-D-P-R-B", "I-W-X-P-V", "T-M-P-I-O",
"W-Y-D-J-K", "A-O-C-L-B", "S-R-O-Y-C",
"A-O-Y-N-W", "P-C-O-D-Y", "E-S-A-L-Y",
"E-O-Q-W-C", "U-O-A-X-Q", "W-E-N-Y-D",
"A-W-J-Z-X", "P-L-R-U-K", "V-J-E-K-Z",
"V-A-M-G-D", "N-C-F-M-G", "H-W-N-K-R",
"G-T-A-F-O", "K-F-V-G-S", "N-V-H-G-I",
"F-Y-T-S-G", "A-H-O-C-V", "Q-W-J-S-C",
"W-G-I-X-E", "D-B-V-A-N", "P-N-L-Y-Q",
"O-I-R-Q-U", "D-R-W-E-O", "W-X-U-V-P",
"X-Y-D-A-W", "M-J-B-S-G", "K-R-G-N-Y",
"O-B-K-L-M", "G-N-Y-X-D", "K-F-A-B-T",
"S-Z-R-L-A", "K-Y-W-X-A", "O-Q-X-I-D",
"I-L-R-M-X", "S-D-V-U-N", "B-W-F-A-T",
"A-W-X-R-J", "D-H-G-X-L", "E-C-V-U-T",
"D-W-P-Z-F", "V-O-M-P-R", "P-L-B-X-N",
"Z-U-F-D-V", "M-K-Z-S-Y", "X-P-N-T-D",
"U-Q-D-T-S", "N-I-X-S-O", "S-C-K-F-D",
"N-V-I-R-D", "Z-X-Y-B-P", "U-W-R-D-V",
"G-V-I-N-K", "D-Y-N-T-J", "P-K-F-U-W",
"U-I-P-D-Q", "R-T-Q-N-Z", "Z-R-D-V-O",
"Z-S-F-T-D", "X-K-Z-B-W", "U-F-Z-S-Y",
"X-I-T-Z-K", "A-X-H-N-Z", "R-U-Q-W-J",
"C-H-P-V-Y", "R-O-A-T-E", "L-F-B-X-A",
"Z-X-E-C-G", "R-B-C-Q-W", "A-O-Z-U-B",
"R-W-P-S-H", "R-Y-B-A-W", "K-X-U-I-M",
"O-X-F-P-A", "U-Y-P-D-M", "A-D-K-R-M",
"R-U-D-T-M", "H-Q-Y-K-J", "T-B-H-N-U",
"P-I-V-X-W", "S-H-X-C-U", "I-O-Y-G-W",
"A-U-Z-J-R", "Q-U-H-M-A", "B-W-M-I-C",
"P-X-Z-Y-N", "Y-J-W-N-B", "V-Y-U-S-B",
"K-W-S-Q-M", "I-K-X-H-S", "F-L-M-Q-T",
"S-Z-O-K-L", "O-P-N-G-E", "P-H-R-Q-T",
"M-L-A-D-T", "D-S-X-V-H", "F-C-O-A-B",
"P-I-N-O-H", "H-X-Y-I-C", "S-I-R-P-Q",
"P-M-F-H-Y", "S-R-O-T-Q", "X-H-O-B-R",
"W-P-A-Q-V", "E-L-Q-G-Y", "I-S-T-W-C",
"B-M-R-G-Y", "S-J-A-K-Q", "E-P-B-G-J",
"R-Y-E-L-D", "A-R-C-N-S", "Y-H-B-M-I",
"T-Q-C-K-N", "L-T-Z-V-C", "Q-L-N-J-K",
"T-E-J-M-Y", "E-M-F-R-C", "M-A-Y-D-I",
"G-M-Y-F-Q", "A-X-B-E-N", "F-Y-E-H-L",
"S-Z-R-M-O", "U-V-W-S-I", "D-S-E-L-K",
"B-C-X-V-F", "Q-V-L-F-H", "H-Z-I-J-P",
"W-U-O-M-D", "A-Y-T-O-X", "Y-C-Z-V-D",
"E-L-O-X-Y", "D-U-K-X-A", "S-W-K-N-E",
"D-F-T-E-Y", "J-T-B-C-L", "E-T-Z-V-F",
"Q-D-U-P-E", "M-Q-X-T-J", "A-M-I-K-P",
"J-T-B-E-R", "L-X-J-O-F", "X-B-V-W-P",
"Y-N-H-G-Z", "M-F-K-S-P", "K-B-V-Z-L",
"T-L-Y-G-A", "N-U-X-C-D", "W-B-O-X-Z",
"U-Y-J-F-A", "T-V-J-I-S", "T-L-W-X-Z",
"V-K-X-C-N", "G-C-I-S-Z", "C-T-K-S-Z",
"F-I-D-N-E", "E-C-M-Y-J", "N-C-Y-S-I",
"B-N-I-L-D", "Y-F-T-M-V", "R-A-E-O-M",
"M-G-P-W-X", "H-B-C-D-R", "A-J-N-C-H",
"R-O-F-D-N", "H-E-R-T-K", "M-U-S-V-A",
"L-V-F-A-H", "E-Q-N-Y-C", "T-N-L-X-S",
"C-F-X-A-N", "M-X-Y-C-Z", "A-N-F-B-K",
"J-Q-R-Z-D", "Q-P-Y-G-N", "D-Y-O-R-J",
"K-R-Y-N-O", "A-H-K-J-B", "O-G-J-A-S",
"T-N-K-X-S", "V-P-X-Y-F", "R-P-V-G-T",
"O-B-F-E-D", "Z-P-I-T-F", "T-S-D-X-G",
"Y-J-P-Z-U", "H-W-Y-K-J", "H-Z-C-F-Q",
"D-I-B-N-X", "K-B-U-H-E", "H-Y-U-Q-A",
"N-Q-G-T-I", "J-B-V-E-G", "M-F-O-E-H",
"B-P-K-M-I", "T-Z-B-Q-Y", "X-Y-T-P-O",
"E-K-I-W-C", "C-M-R-S-Y", "F-Y-M-W-L",
"A-S-E-U-J", "I-P-W-N-G", "V-G-R-E-T",
"H-O-W-G-Y", "O-H-B-C-P", "C-Y-D-Q-X",
"X-Y-I-Z-U", "R-I-Q-Y-P", "E-M-L-D-Y",
"B-G-P-Y-T", "Z-H-X-D-V", "S-B-R-J-F",
"O-T-X-P-W", "Y-C-T-M-E", "J-A-D-O-P",
"B-W-Q-D-I", "Y-T-X-K-Q", "F-D-P-X-J",
"Z-G-Y-O-N", "J-N-Z-Q-P", "W-C-E-I-U",
"L-R-K-F-H", "X-I-G-B-O", "M-C-Q-Y-Z",
"S-T-W-J-E", "G-O-N-Y-Q", "O-Q-R-Z-B",
"X-G-E-C-I", "P-B-D-F-Q", "Q-H-D-I-V",
"H-I-J-D-Q", "C-B-S-I-G", "M-A-F-D-B",
"G-Z-R-U-K", "N-U-L-Q-R", "C-A-K-M-T",
"F-S-R-B-K", "O-D-X-S-W", "H-J-N-P-C",
"N-G-Y-L-J", "D-X-K-O-E", "F-E-H-D-L",
"E-M-D-P-Z", "Q-K-I-J-V", "D-O-N-M-X",
"C-P-N-E-K", "L-H-T-U-P", "M-T-Z-P-H",
"B-T-L-Z-G", "Z-V-R-C-I", "J-M-R-D-G",
"I-V-L-Q-T", "O-V-X-A-M", "V-L-N-A-T",
"M-B-R-U-O", "O-B-Q-F-X", "H-O-E-K-G",
"S-H-G-B-D", "N-Z-C-L-D", "M-F-J-H-K",
"A-O-D-W-B", "I-X-G-K-W", "B-S-O-K-Q",
"X-T-Z-I-D", "N-D-G-B-L", "Z-O-U-I-X",
"W-B-A-R-H", "S-G-Q-J-F", "M-B-J-F-A",
"M-B-X-A-P", "F-M-S-Y-V", "T-K-B-G-C",
"H-V-C-G-X", "V-A-S-I-T", "Z-X-G-U-S",
"U-J-Y-M-H", "D-Y-H-X-S", "T-Q-X-I-E",
"S-V-K-M-T", "S-Z-P-O-Y", "V-Y-Q-L-F",
"A-E-R-V-G", "E-C-M-G-O", "T-B-U-M-V",
"M-R-V-A-E", "C-A-R-W-N", "Y-U-D-Z-X",
"Y-G-Z-C-Q", "T-X-R-A-D", "S-A-U-R-K",
"E-A-D-R-V", "P-R-T-W-F", "A-Z-Y-O-N",
"O-P-W-A-I", "H-V-U-R-F", "W-D-G-P-I",
"M-Z-Q-C-I", "Y-S-H-W-I", "F-J-C-N-S",
"H-C-Z-Y-K", "W-J-K-Z-I", "Q-T-G-C-X",
"S-Q-T-O-Y", "Z-G-T-W-X", "X-M-J-R-W",
"S-Y-N-F-H", "C-F-V-G-A", "W-R-J-I-B",
"I-V-B-A-M", "R-C-D-L-U", "S-T-B-A-N",
"F-W-J-M-A", "J-I-R-E-H", "Q-D-O-E-R",
"R-B-M-O-J", "B-X-G-V-U", "R-J-L-Y-M",
"R-F-A-X-J", "N-I-J-V-Q", "J-O-D-Q-Z",
"K-I-F-D-H", "N-H-Q-Z-M", "I-K-R-Z-X",
"O-D-U-T-I", "K-G-S-L-Y", "X-D-O-K-A",
"C-X-I-P-J", "X-A-Y-V-T", "I-V-T-J-O",
"X-D-M-H-U", "M-L-R-Y-J", "N-L-I-R-B",
"A-J-Z-O-Q", "G-Y-I-S-E", "N-F-X-Z-T",
"U-G-C-F-K", "R-N-W-S-M", "A-O-T-N-U",
"W-O-P-G-V", "D-W-E-H-O", "B-D-S-E-Z",
"C-L-V-M-I", "Y-N-C-W-B", "C-Q-L-P-W",
"X-H-L-B-M", "H-V-D-K-Q", "O-S-C-U-H",
"V-I-J-K-A", "D-M-B-I-F", "O-H-N-J-V",
"R-L-Q-J-Y", "Q-P-B-S-X", "J-K-V-H-F",
"A-T-L-Q-B", "E-D-S-B-G", "K-T-X-J-Q",
"W-L-U-B-H", "T-Y-Z-G-V", "G-S-C-X-P",
"D-C-M-Z-Y", "V-G-F-D-E", "Q-F-X-O-U",
"E-V-L-F-G", "M-T-V-U-Y", "Z-X-S-U-E",
"J-I-F-E-R", "C-V-J-R-W", "W-R-V-U-K",
"M-A-S-U-Q", "J-K-O-F-I", "I-Y-G-U-Z",
"B-Y-V-D-R", "M-G-Q-N-J", "A-F-N-K-M",
"R-B-D-Q-P", "H-T-N-U-L", "J-W-E-A-B",
"N-M-K-R-O", "H-Q-A-N-E", "U-B-Y-L-Q",
"J-E-N-T-Q", "D-N-L-R-E", "K-S-O-L-Z",
"Z-D-Y-A-N", "D-Q-B-X-Z", "J-E-F-O-Q",
"U-E-Q-T-R", "U-H-F-N-L", "C-T-I-V-X",
"V-L-Q-O-K", "G-Q-D-P-V", "D-T-V-G-S",
"I-G-H-Z-L", "A-E-I-Y-B", "S-V-N-B-R",
"M-P-J-Y-N", "D-T-W-Q-Z", "U-V-F-A-S",
"M-B-T-Y-Q", "F-I-C-D-X", "G-X-O-K-J",
"J-M-I-E-D", "C-B-S-F-A", "A-Y-O-Z-P",
"R-T-H-L-S", "P-X-B-S-O", "B-I-C-P-T",
"F-K-H-Z-N", "R-D-Y-T-P", "S-U-P-G-R",
"M-K-R-Q-V", "Z-E-O-U-T", "M-W-Y-X-C",
"Q-J-U-T-B", "L-H-S-J-U", "P-M-X-R-N",
"S-Y-T-G-W", "W-P-N-V-O", "E-U-I-L-M",
"V-S-K-J-R", "P-E-T-C-X", "E-V-C-S-Y",
"M-S-F-T-Q", "L-D-P-K-T", "D-Z-U-Q-P",
"D-H-L-W-N", "V-U-Q-I-A", "L-D-G-H-V",
"G-I-U-Q-E", "G-E-D-R-H", "N-T-L-K-H",
"J-U-K-F-V", "G-J-Y-K-W", "E-A-I-G-Q",
"S-U-H-R-T", "L-S-W-H-C", "P-V-I-Y-O",
"E-L-K-X-N", "Y-B-S-T-N", "N-U-V-E-Z",
"B-V-K-M-O", "L-V-H-A-K", "M-U-T-J-K",
"V-J-T-F-R", "T-Y-E-U-W", "C-D-B-A-L",
"K-E-U-S-A", "D-H-R-X-Z", "M-B-Z-G-C",
"P-E-T-S-Y", "M-G-O-J-F", "C-Y-E-P-X",
"R-V-D-C-N", "S-Y-A-K-Z", "K-S-G-T-D",
"D-F-G-U-K", "F-B-P-T-M", "P-G-O-D-W",
"U-L-I-R-J", "F-Q-N-X-J", "D-Q-F-V-B",
"R-P-E-Z-H", "A-H-X-M-L", "I-H-F-G-W",
"V-C-M-H-Y", "V-H-L-Y-F", "H-I-L-P-V",
"L-Q-W-K-A", "D-W-J-R-L", "W-E-V-J-L",
"F-Z-X-U-H", "K-U-Q-I-R", "S-D-N-E-V",
"G-T-E-L-Y", "S-P-E-B-D", "U-N-L-S-O",
"Z-G-W-I-X", "M-C-X-S-E", "P-C-S-X-Y",
"B-Z-K-R-H", "D-J-W-Y-U", "J-O-Q-F-P",
"I-A-V-G-Y", "U-B-V-G-N", "W-H-Q-M-E",
"J-R-O-D-F", "W-M-C-O-P", "R-I-F-M-Q",
"Q-L-D-W-X", "M-A-Q-P-F", "O-J-T-L-A",
"X-S-I-P-G", "G-W-D-Y-F", "T-B-M-N-J",
"Q-W-N-Z-C", "M-F-C-O-H", "Z-N-Q-X-P",
"Q-G-A-Y-C", "R-F-G-P-E", "X-J-F-R-C",
"J-S-Q-E-L", "O-K-P-F-D", "R-J-W-G-T",
"Y-P-J-N-D", "N-S-F-Y-T", "M-L-N-H-U",
"V-A-H-G-Q", "H-L-W-K-P", "U-P-G-V-O",
"V-N-P-I-Y", "A-O-E-F-L", "W-F-Q-J-G",
"B-A-L-V-Q", "Y-J-F-V-S", "O-F-E-J-A",
"X-O-F-M-B", "B-M-L-H-W", "Z-X-F-T-B",
"W-X-E-M-A", "F-J-V-W-L", "P-C-U-R-O",
"S-K-F-D-V", "K-F-Z-Q-C", "J-S-R-M-Q",
"E-H-L-Q-N", "W-F-M-E-X", "P-R-E-N-A",
"D-F-G-N-Y", "I-S-O-V-T", "R-I-C-N-L",
"I-T-C-Y-P", "R-W-I-K-X", "P-B-J-X-G",
"D-W-F-N-E", "M-G-C-B-K", "E-T-H-F-W",
"A-E-L-F-Z", "Z-V-W-S-R", "O-T-L-D-Q",
"S-E-M-Z-O", "N-R-Y-A-U", "Y-D-M-A-R",
"S-M-P-N-K", "C-T-B-L-Z", "X-A-L-I-V",
"B-V-M-G-S", "N-R-K-Q-D", "F-O-L-X-Y",
"Y-T-F-A-S", "X-G-O-U-A", "Z-F-I-B-T",
"V-H-B-N-W", "V-K-B-W-S", "V-C-T-L-G",
"X-N-L-Y-Q", "N-D-L-I-Z", "L-K-G-N-E",
"D-L-M-K-Z", "E-I-P-Z-U", "H-X-B-C-D",
"B-H-D-C-V", "F-O-L-D-R", "B-Z-J-Y-V",
"E-C-R-B-S", "E-X-V-B-S", "P-K-I-W-G",
"A-I-F-V-O", "D-F-R-I-E", "X-L-I-N-O",
"P-Y-Q-C-S", "C-P-A-X-L", "W-O-U-A-X",
"H-M-R-E-B", "K-Y-P-G-A", "O-E-V-D-C",
"Z-A-K-M-W", "S-F-M-Z-E", "X-U-I-C-J",
"C-V-T-B-N", "Z-Q-Y-V-G", "T-W-G-Q-D",
"K-Y-L-R-F", "W-O-S-E-A", "V-T-Q-F-G",
"G-V-J-M-U", "P-R-A-N-C", "I-R-A-F-T",
"X-Z-U-W-N", "A-G-R-D-Y", "J-U-T-A-Q",
"K-Y-T-H-U", "P-Q-L-Z-G", "N-K-Y-X-W",
"A-T-M-R-Z", "M-B-P-C-L", "M-Q-K-N-R",
"I-W-H-G-R", "I-F-D-Q-A", "V-G-F-C-X",
"H-Q-F-D-T", "N-R-T-Q-G", "X-V-P-B-G",
"V-H-B-N-X", "G-Q-T-J-Y", "P-F-A-N-H",
"C-D-I-W-K", "T-R-J-B-P", "E-P-X-L-S",
"O-K-B-L-M", "Z-T-B-R-V", "V-N-Y-Z-U",
"E-W-V-F-O", "D-S-A-Z-J", "R-O-W-A-Y",
"V-L-K-J-Q", "Q-T-J-S-Z", "M-G-L-Y-D",
"G-U-W-I-C", "G-O-D-T-I", "R-L-Z-P-V",
"W-G-M-T-I", "S-F-H-Z-J", "Z-L-O-V-N",
"G-D-A-U-H", "Y-K-V-R-E", "Y-O-L-R-I",
"X-V-Z-I-B", "N-Z-S-D-O", "N-X-Z-J-M",
"S-X-A-H-C", "V-T-R-F-H", "K-E-Q-B-J",
"V-R-J-U-G", "Q-K-B-P-Z", "Y-I-S-X-K",
"U-O-R-Q-J", "Q-T-X-F-D", "P-O-F-B-J",
"C-M-K-L-F", "N-W-Y-A-V", "E-H-I-G-U",
"L-J-X-A-C", "Q-K-U-D-B", "A-S-R-D-T",
"S-Z-E-Y-U", "A-K-R-S-G", "S-F-R-J-Q",
"A-Y-J-F-U", "L-I-J-R-H", "K-C-V-Q-F",
"H-U-A-T-D", "E-W-L-I-C", "Y-P-R-F-V",
"L-M-P-Z-U", "T-Q-U-P-V", "Q-W-T-M-K",
"P-D-G-Y-K", "F-I-K-C-P", "I-T-Y-K-L",
"H-T-K-I-R", "H-K-B-M-F", "J-P-D-Z-Q",
"D-M-K-C-V", "E-K-Y-F-R", "P-L-H-A-J",
"R-C-Z-V-T", "I-W-G-A-T", "Y-N-X-K-R",
"M-N-E-C-Q", "J-B-W-R-X", "R-M-D-T-F",
"R-V-L-Y-G", "M-V-E-Z-Q", "S-H-Q-X-G",
"H-P-Y-Q-G", "F-N-K-T-W", "I-B-Z-P-F",
"G-P-N-S-F", "B-Y-S-N-A", "P-I-Z-A-S",
"X-I-K-B-Y", "B-Q-F-W-M", "Y-E-J-P-M",
"V-E-T-G-O", "M-N-L-K-I", "N-D-W-B-V",
"F-P-S-M-X", "K-H-Q-M-F", "Z-B-O-I-L",
"L-F-D-S-E", "W-Y-P-B-A", "L-P-S-V-U",
"D-G-L-J-P", "K-U-F-Y-E", "J-G-R-M-N",
"J-U-P-H-O", "O-U-N-M-W", "X-V-J-K-E",
"C-W-G-L-K", "D-H-A-O-K", "H-G-C-X-P",
"B-C-I-J-D", "N-L-T-D-S", "X-D-C-A-T",
"Z-D-U-N-E", "P-W-A-I-L", "N-U-G-H-C",
"F-Q-E-V-T", "X-O-M-S-U", "Z-V-S-Q-R",
"K-Z-U-D-L", "A-O-Z-C-T", "S-K-U-T-Q",
"V-Q-I-B-Z", "A-K-Z-N-Y", "T-G-V-Y-O",
"G-K-R-A-J", "Y-J-F-T-U", "E-P-K-G-F",
"U-P-X-L-V", "H-C-S-M-I", "K-D-X-W-N",
"F-E-P-V-R", "C-P-V-W-L", "I-S-M-E-B",
"D-E-L-C-O", "A-D-V-U-W", "D-I-N-M-Z",
"O-Z-K-S-N", "F-J-W-L-S", "H-C-V-W-I",
"B-A-L-V-Y", "N-K-Z-W-X", "Z-C-X-K-A",
"S-X-H-G-Y", "L-G-M-V-Q", "Z-L-G-Y-Q",
"J-W-E-A-D", "G-S-A-M-U", "F-M-D-K-O",
"B-O-G-R-K", "V-S-U-Q-B", "R-X-O-N-F",
"Y-N-M-H-I", "T-J-W-Q-L", "R-W-P-B-H",
"D-A-I-P-E", "D-P-Q-T-N", "Y-K-Q-U-X",
"A-Y-M-C-R", "M-O-I-L-B", "Y-O-K-J-F",
"O-C-J-X-H", "W-J-X-L-Z", "F-P-H-A-L",
"M-T-F-U-P", "W-H-F-C-X", "R-C-D-Z-L",
"Y-B-A-I-L", "S-I-Y-W-P", "K-D-X-G-Z",
"O-W-Q-M-G", "M-T-V-L-G", "F-Z-Y-J-L",
"V-L-A-S-N", "I-P-A-S-N", "G-T-Q-D-F",
"G-R-L-W-V", "I-R-Z-V-P", "M-L-B-A-I",
"D-K-Z-F-M", "M-O-G-X-V", "Y-V-D-Z-W",
"M-S-O-G-T", "Z-F-M-U-X", "V-N-Z-P-I",
"N-D-F-U-J", "G-O-U-E-S", "Z-C-G-W-B",
"O-T-E-N-V", "W-P-H-C-V", "X-R-D-P-G",
"Y-C-E-F-T", "V-O-G-K-I", "S-I-W-M-L",
"M-H-C-O-A", "Q-C-N-Z-D", "A-N-L-S-T",
"X-W-I-L-K", "A-Y-V-S-K", "D-W-F-L-K",
"U-Z-I-R-Q", "V-W-B-A-T", "I-U-R-E-W",
"N-W-U-Q-O", "F-H-L-N-O", "D-I-T-J-H",
"W-K-Q-D-T", "A-O-R-I-U", "M-E-V-A-F",
"U-J-M-X-S", "O-E-R-K-H", "A-V-Z-T-D",
"C-Z-B-D-L", "D-J-T-Q-G", "A-O-C-I-Z",
"J-L-A-Y-C", "P-O-H-E-V", "A-M-Z-I-R",
"W-C-R-H-V", "Z-G-I-V-N", "K-M-W-T-Q",
"O-I-F-D-N", "X-D-A-V-T", "T-S-M-B-D",
"F-C-D-U-Q", "B-H-M-Q-G", "M-K-I-W-B",
"R-M-Q-W-P", "N-Z-L-F-G", "I-P-J-B-W",
"O-Y-W-U-V", "C-V-Z-B-O", "O-Q-S-F-X",
"B-G-F-M-W", "N-X-R-P-S", "L-T-A-H-R",
"G-O-E-L-X", "R-I-U-X-Y", "Q-O-Z-F-V",
"O-P-J-C-M", "D-W-G-S-L", "T-K-W-L-O",
"E-I-O-K-D", "K-E-A-I-S", "M-I-W-F-K",
"S-W-G-T-N", "P-L-J-D-A", "O-M-T-J-P",
"C-R-Z-L-G", "F-S-D-V-K", "N-J-H-V-I",
"D-I-A-F-J", "U-R-T-V-X", "J-N-T-R-S",
"K-V-Z-T-Q", "J-L-C-R-M", "Z-A-R-L-E",
"Y-L-W-I-S", "B-W-E-N-U", "B-S-W-J-F",
"D-G-I-P-S", "D-Q-M-E-R", "K-T-R-A-D",
"P-Q-L-E-U", "U-D-W-A-O", "Q-R-P-D-Y",
"C-X-V-S-I", "F-E-U-I-K", "H-Z-T-L-P",
"P-I-U-B-O", "S-Q-G-W-K", "K-V-S-U-L",
"F-N-Q-O-P", "M-Q-F-C-L", "V-X-G-C-A",
"N-S-E-C-V", "R-K-J-A-X", "D-L-H-W-S",
"Z-C-Y-L-G", "M-D-W-F-U", "R-A-U-S-F",
"Y-W-H-V-Q", "B-K-G-J-W", "B-V-H-E-C",
"D-J-X-S-H", "W-C-H-Z-Q", "X-B-A-I-U",
"D-A-J-C-F", "B-P-U-S-W", "A-D-R-Z-K",
"S-H-P-A-Z", "J-O-U-P-S", "W-C-H-P-T",
"C-U-Z-O-W", "P-E-H-M-S", "B-W-L-Y-N",
"N-S-F-R-Y", "W-R-K-A-N", "G-X-V-D-E",
"I-G-D-P-T", "W-N-J-R-L", "P-Q-H-A-V",
"U-Q-R-P-W", "I-H-Q-X-U", "W-K-R-M-N",
"U-H-Q-B-Y", "X-P-D-V-W", "E-K-F-R-C",
"T-E-B-N-L", "I-S-K-Q-H", "Y-Z-V-Q-L",
"W-L-U-P-I", "Y-P-F-H-O", "M-C-Y-T-I",
"Q-A-V-Z-O", "I-H-U-K-F", "Q-Z-C-W-Y",
"U-M-Q-C-R", "U-H-S-M-W", "R-C-M-Y-G",
"R-C-J-A-V", "X-B-Z-C-Y", "P-C-O-J-I",
"E-C-O-W-R", "E-T-Y-X-F", "Q-M-C-K-S",
"H-I-O-J-K", "R-P-N-J-V", "H-Y-P-N-V",
"R-J-I-L-S", "N-K-T-Z-O", "H-B-K-A-P",
"P-G-J-A-B", "L-S-O-I-Y", "L-U-R-Z-D",
"F-I-K-Q-B", "Q-K-X-B-M", "A-C-L-B-I",
"J-E-O-D-K", "Y-W-V-G-D", "S-N-T-H-Q",
"K-M-D-R-H", "B-U-N-A-T", "A-J-F-O-C",
"J-L-V-R-D", "X-A-Q-J-R", "I-V-E-W-Z",
"Q-G-K-P-X", "O-H-K-J-D", "N-K-I-J-B",
"Y-R-N-G-C", "K-L-E-B-S", "O-P-T-D-G",
"O-R-E-J-V", "X-V-B-Z-U", "Y-H-I-O-C",
"B-O-Y-M-P", "J-Z-R-Q-P", "A-E-K-M-D",
"D-X-L-F-U", "J-X-U-A-Z", "Y-R-G-X-Q",
"Y-R-P-W-C", "K-Q-C-Y-L", "K-H-L-V-U",
"P-A-N-I-C", "M-D-Y-F-A", "H-V-D-F-U",
"Z-D-P-U-J", "O-E-I-Z-Q", "L-Q-A-O-I",
"L-V-C-K-N", "E-Z-R-Q-K", "N-T-V-U-D",
"U-B-O-H-Z", "F-X-D-H-U", "T-W-R-O-G",
"G-A-O-Z-L", "Z-C-B-G-P", "O-I-B-S-N",
"Z-R-I-O-Y", "K-B-L-C-Z", "Z-B-T-F-D",
"B-H-P-J-C", "A-T-L-N-M", "O-P-W-M-S",
"Q-I-L-G-J", "O-D-Q-J-M", "P-B-F-Z-V",
"Q-H-J-I-C", "K-V-W-Z-D", "Y-A-R-Z-Q",
"M-U-H-Q-N", "O-D-K-J-Z", "I-C-Z-J-H",
"E-K-R-G-M", "D-B-G-Y-K", "U-Q-B-C-L",
"Y-Q-M-W-L", "A-Z-J-B-S", "C-W-K-O-X",
"G-E-V-B-R", "L-N-Q-T-H", "H-E-X-A-J",
"U-O-Z-S-B", "P-G-W-K-D", "J-W-L-C-A",
"L-C-E-V-Z", "T-K-Y-Q-P", "Z-J-Q-U-V",
"V-C-P-K-X", "U-X-A-H-E", "I-J-E-Z-W",
"O-M-W-F-S", "N-K-Y-P-M", "C-G-K-L-R",
"M-T-V-A-E", "D-V-H-Q-F", "M-N-P-W-L",
"G-E-F-T-M", "G-X-D-Q-O", "X-G-W-E-Z",
"U-C-B-P-Z", "F-K-Z-W-H", "P-C-D-F-L",
"N-V-G-R-T", "I-N-B-J-T", "B-T-A-M-L",
"Q-D-N-Y-I", "B-I-K-X-A", "C-U-F-S-K",
"W-X-G-P-L", "H-A-P-L-C", "W-T-K-P-F",
"G-B-U-T-K", "U-S-Q-Y-Z", "G-C-E-Z-W",
"Z-Y-Q-B-M", "D-Y-N-C-E", "E-J-Q-K-I",
"P-R-O-B-V", "D-E-A-S-U", "I-A-M-E-L",
"M-K-U-F-Y", "L-Q-H-S-O", "Z-F-V-T-P",
"V-N-M-R-J", "Q-E-P-K-O", "O-H-J-U-K",
"U-Z-Q-O-F", "R-X-K-O-C", "L-R-K-C-G",
"V-F-B-S-K", "L-Z-O-H-E", "D-S-Y-V-K",
"R-J-V-A-C", "P-L-B-Q-Z", "U-Q-Z-X-Y",
"E-P-L-F-T", "Z-F-C-G-B", "W-V-C-A-J",
"O-N-C-Y-H", "B-Y-C-D-Z", "E-X-G-H-Z",
"Y-H-X-J-I", "O-K-P-J-D", "G-E-K-T-B",
"G-A-K-Y-P", "T-V-X-P-H", "W-Y-D-K-V",
"Z-W-B-P-Q", "A-J-F-U-P", "V-A-X-E-Z",
"F-T-J-E-I", "V-M-L-Z-U", "H-I-B-L-Q",
"C-D-V-K-M", "G-Z-F-J-R", "C-T-N-U-H",
"W-Y-U-X-M", "T-F-I-W-V", "X-O-P-Y-W",
"L-Z-P-B-K", "A-E-T-Q-K", "K-P-C-T-Z",
"C-A-H-G-E", "B-W-G-D-V", "A-S-D-B-I",
"T-D-G-C-P", "J-B-F-T-K", "V-R-L-U-F",
"O-P-Q-X-M", "K-M-T-E-D", "R-B-H-X-G",
"L-C-O-Y-B", "R-Z-U-E-I", "K-I-W-O-G",
"Z-X-W-F-K", "Y-C-B-S-V", "L-M-R-N-Z",
"B-Q-M-Z-K", "P-S-Z-O-T", "Y-A-Z-N-R",
"L-O-A-P-J", "O-Z-Y-M-P", "C-P-S-J-Q",
"Y-F-Q-A-R", "U-Z-K-B-X", "Q-R-T-H-X",
"N-U-E-Q-A", "X-Z-R-J-C", "U-X-E-A-Z",
"Y-M-O-A-V", "N-K-D-W-M", "V-Q-E-F-S",
"L-U-A-Z-D", "X-S-R-P-E", "I-B-O-Z-L",
"J-G-K-H-Z", "T-P-O-Z-S", "L-I-R-G-N",
"Y-C-O-Z-A", "H-B-D-Q-R", "C-L-J-E-T",
"K-Z-N-U-X", "P-F-S-Z-H", "S-N-D-R-T",
"V-R-S-T-G", "N-S-F-U-Y", "D-P-L-C-A",
"B-X-V-M-S", "B-M-Z-E-Q", "K-Y-S-P-B",
"K-T-V-F-G", "U-Z-B-W-E", "J-X-O-C-Y",
"X-C-Q-P-D", "X-L-Y-J-Z", "Y-F-O-N-H",
"M-J-B-Z-X", "G-X-R-A-D", "E-I-L-O-A",
"B-R-C-I-K", "K-W-F-N-P", "C-Y-R-A-H",
"J-H-D-N-C", "P-Y-C-I-D", "P-D-C-U-E",
"H-A-I-E-P", "B-N-E-H-S", "C-Y-P-E-F",
"K-F-X-B-S", "M-Q-D-I-Z", "V-S-P-K-O",
"L-W-M-T-I", "K-N-B-V-D", "A-Z-N-X-G",
"U-T-D-A-Y", "Q-Z-D-F-E", "J-Q-I-Y-C",
"G-L-E-O-R", "V-J-Z-K-F", "O-W-F-X-H",
"H-R-P-X-L", "B-F-X-G-P", "I-C-A-M-R",
"P-N-W-Z-L", "R-G-O-H-D", "G-M-B-W-K",
"G-D-E-H-P", "Z-K-I-P-N", "K-V-C-E-W",
"O-K-N-T-R", "K-B-N-X-M", "E-V-A-X-P",
"Q-J-I-Y-C", "I-T-U-J-D", "W-U-T-O-Q",
"O-E-H-J-A", "D-K-P-A-I", "D-J-A-F-X",
"T-X-D-V-A", "B-W-T-H-V", "H-G-Q-E-U",
"B-U-F-Z-Y", "O-S-R-T-D", "F-W-S-I-G",
"Z-O-X-C-S", "H-V-K-N-E", "Z-M-L-E-O",
"Q-V-T-M-P", "T-N-D-C-S", "L-F-Q-R-Y",
"U-F-S-I-O", "S-R-M-B-K", "D-P-W-U-A",
"Y-W-A-T-E", "I-W-A-F-J", "V-J-G-A-Q",
"Z-S-C-Y-L", "T-C-N-O-S", "J-R-Y-X-Q",
"A-F-P-N-J", "R-Y-N-H-M", "S-W-Q-B-V",
"N-Q-U-G-K", "T-A-Y-R-Z", "I-L-O-U-V",
"W-B-L-F-Q", "N-T-E-W-G", "L-S-I-W-X",
"P-A-Z-J-U", "Z-N-F-X-G", "P-B-O-E-N",
"D-U-T-C-K", "G-Y-I-K-S", "F-H-W-X-P",
"O-B-T-E-Z", "N-K-T-S-X", "E-S-T-N-V",
"E-A-J-Q-F", "P-Q-D-X-B", "R-F-J-E-Q",
"X-Z-S-M-V", "E-Z-Q-D-X", "M-O-T-U-D",
"O-I-X-Z-H", "H-T-V-I-M", "U-E-A-D-W",
"Z-D-F-A-X", "E-D-V-P-N", "K-J-R-M-H",
"V-A-K-U-D", "S-B-L-A-N", "Q-C-Z-D-P",
"U-Z-A-W-C", "V-D-M-G-B", "Z-H-A-I-X",
"W-F-H-R-X", "G-E-V-F-K", "H-A-V-L-E",
"K-P-E-X-Y", "T-O-Y-R-P", "H-T-F-U-K",
"R-V-N-C-X", "K-H-Z-R-A", "Q-P-J-G-N",
"T-F-L-K-E", "E-T-O-D-G", "J-K-E-S-N",
"K-Q-D-C-B", "Q-R-A-F-D", "J-W-A-Q-I",
"N-T-F-G-D", "E-R-I-D-N", "M-G-P-Q-V",
"D-P-R-G-N", "N-C-F-T-A", "D-F-Q-X-O",
"U-D-K-Q-X", "N-G-M-Q-A", "I-X-F-D-V",
"R-T-C-K-I", "S-G-E-R-O", "R-B-J-G-Z",
"J-X-G-K-R", "U-K-O-L-C", "X-Q-U-S-B",
"B-A-M-V-N", "N-A-V-G-U", "I-Y-U-Z-C",
"Y-R-I-M-V", "Y-I-R-P-N", "E-C-Q-A-P",
"P-Z-B-O-A", "D-A-R-F-Y", "Q-E-T-L-N",
"Z-D-F-Q-C", "X-T-Q-W-D", "D-P-Y-U-J",
"S-J-Q-X-V", "E-O-P-W-N", "W-Q-B-O-Y",
"Y-Z-W-Q-F", "H-Q-C-X-O", "S-B-W-V-L",
"G-R-Y-V-J", "W-F-G-K-S", "F-N-P-D-S",
"L-C-Q-T-Z", "V-S-Y-O-B", "L-F-X-U-Q",
"G-D-R-M-E", "P-Q-R-Y-G", "N-E-H-L-P",
"Z-R-F-M-U", "I-X-C-F-O", "L-E-X-K-O",
"G-V-Y-X-F", "O-P-V-A-Z", "P-K-S-L-Y",
"Q-R-K-M-D", "A-N-B-J-R", "C-S-G-R-M",
"H-C-E-O-D", "E-I-N-F-O", "F-S-P-O-B",
"T-S-A-X-B", "R-K-Y-L-M", "F-G-O-C-T",
"C-F-H-Y-Z", "M-P-Z-A-V", "N-U-X-B-T",
"Q-A-V-N-P", "D-R-V-C-K", "U-P-X-M-F",
"S-P-I-T-Z", "O-Z-C-U-Y", "B-G-X-A-D",
"Y-U-L-A-W", "O-J-Q-W-G", "V-B-I-F-D",
"V-J-Q-K-A", "H-X-W-S-A", "E-D-F-T-I",
"H-Q-V-R-L", "M-U-Z-K-Q", "V-Y-U-Q-X",
"H-M-I-U-O", "N-Q-P-U-R", "Y-F-I-V-D",
"F-A-L-W-M", "G-Q-M-L-B", "X-B-L-P-W",
"I-A-R-Q-F", "U-E-J-T-V", "O-B-Q-U-S",
"B-P-U-S-M", "N-Z-D-O-V", "A-X-S-T-V",
"O-Y-C-F-K", "D-S-I-M-Y", "B-Y-N-G-I",
"G-P-U-M-F", "V-B-G-N-W", "C-K-I-S-Y",
"U-B-I-R-V", "L-R-M-C-Z", "T-Z-D-U-M",
"R-M-F-T-O", "S-V-D-F-Y", "M-F-R-C-J",
"G-P-O-X-W", "M-R-X-H-Z", "N-D-J-R-Y",
"B-J-W-U-L", "T-E-U-D-J", "M-V-J-R-B",
"G-X-Z-U-Y", "L-C-P-M-D", "H-Z-W-E-T",
"O-H-Y-C-K", "M-B-Q-N-E", "B-D-E-U-V",
"V-P-F-Y-R", "U-M-C-J-L", "P-X-L-Z-A",
"D-E-F-X-H", "P-I-Z-C-V", "V-N-O-B-G",
"M-T-U-D-P", "I-A-E-O-Q", "V-R-S-L-A",
"S-I-Q-N-T", "A-W-T-O-U", "O-T-V-A-Q",
"D-R-O-Z-F", "Z-M-F-Q-I", "B-H-E-L-M",
"Z-S-D-L-G", "E-B-N-A-Q", "K-Z-O-C-D",
"Y-J-M-C-Z", "K-O-F-A-G", "J-U-L-Y-G",
"A-F-C-V-D", "S-B-H-T-U", "J-F-V-T-Q",
"H-L-Z-K-M", "F-Q-O-K-S", "P-S-U-V-A",
"Y-L-E-D-F", "Z-L-U-K-V", "J-N-M-P-F",
"G-M-F-Y-Z", "W-P-N-D-U", "J-V-Q-H-P",
"Q-B-H-O-R", "U-R-J-K-W", "J-Q-S-O-F",
"S-J-N-T-O", "A-S-B-Q-W", "W-X-Q-H-I",
"K-R-V-S-X", "Q-S-O-R-W", "R-Q-N-G-Z",
"Z-P-A-S-R", "F-N-X-K-D", "S-I-X-A-W",
"K-E-J-H-G", "D-N-Z-W-U", "X-Y-T-J-O",
"X-I-J-Z-S", "R-V-L-W-C", "X-T-A-M-I",
"A-W-B-K-M", "E-C-Q-T-X", "A-B-V-W-X",
"K-O-B-W-Q", "V-Y-F-P-C", "H-O-E-X-D",
"I-Y-A-H-Q", "J-U-N-D-F", "O-V-N-P-Y",
"X-R-O-C-J", "W-I-D-R-M", "Q-C-O-H-N",
"L-Z-Y-W-T", "L-H-J-U-I", "X-M-E-R-U",
"R-J-K-Z-E", "Q-A-I-P-R", "A-D-L-Q-M",
"F-E-M-B-Z", "S-J-N-H-P", "I-Y-C-L-F",
"W-Y-O-N-I", "S-E-N-B-H", "K-Z-E-U-V",
"D-N-Y-Z-O", "Q-S-B-J-P", "J-N-V-T-B",
"U-H-Q-L-S", "U-C-N-Q-L", "A-L-R-Q-F",
"J-Y-K-P-L", "W-S-O-M-U", "L-P-S-U-T",
"U-V-P-F-M", "C-J-W-Q-N", "A-V-C-P-L",
"P-V-N-Y-E", "A-S-M-K-G", "T-U-I-W-H",
"E-K-G-P-M", "Z-F-O-H-E", "C-G-I-X-R",
"R-F-D-O-X", "C-R-F-M-Q", "H-F-M-N-W",
"M-Y-F-I-X", "A-B-U-X-S", "C-F-G-R-D",
"M-A-G-L-C", "W-L-Y-F-U", "U-M-C-R-H",
"A-C-P-Y-K", "A-E-V-C-P", "M-C-A-J-B",
"M-O-Z-G-A", "T-R-E-Y-M", "F-K-E-S-C",
"F-Q-B-J-T", "R-Y-D-V-B", "J-M-C-R-W",
"L-S-E-Z-R", "J-A-E-P-N", "Y-S-K-B-O",
"S-Y-N-G-C", "B-Q-I-W-H", "W-T-U-J-Y",
"O-J-W-G-C", "Q-B-G-I-F", "W-E-B-T-N",
"M-A-U-R-G", "Q-R-O-X-P", "H-T-Y-N-P",
"L-Q-A-G-X", "U-S-D-R-C", "I-J-F-R-Q",
"K-T-G-C-E", "M-K-P-C-T", "W-Z-L-N-K",
"B-O-G-U-P", "C-F-V-D-P", "G-A-P-R-X",
"E-I-Y-K-F", "W-H-G-P-S", "G-J-W-M-B",
"R-Y-B-F-L", "T-F-Y-Q-I", "R-L-O-C-F",
"I-X-S-G-O", "F-R-M-A-X", "H-B-L-Z-A",
"A-L-M-N-C", "F-D-Q-X-L", "Y-K-S-Q-D",
"I-Z-B-O-D", "R-M-A-S-C", "J-S-U-H-T",
"Q-B-A-P-Z", "I-D-X-Q-O", "F-H-S-W-Z",
"P-V-K-R-G", "L-B-A-H-I", "I-P-T-O-Q",
"N-F-K-Y-V", "T-U-M-A-G", "S-N-X-W-F",
"I-V-Y-O-C", "M-T-Z-G-O", "R-V-B-J-I",
"O-X-N-R-V", "W-N-M-F-J", "I-L-R-D-B",
"E-G-F-V-Z", "A-P-S-L-Y", "U-A-X-G-O",
"Y-D-B-O-M", "T-Q-K-M-D", "L-K-D-X-G",
"V-Z-J-A-C", "T-N-I-W-H", "Z-C-S-R-E",
"X-P-C-S-J", "O-A-F-C-R", "P-Z-X-W-E",
"N-L-Q-W-Z", "M-J-W-D-T", "R-S-Q-G-O",
"Z-C-Q-Y-S", "S-J-Y-R-V", "B-H-M-G-A",
"Y-K-D-O-N", "Y-F-G-W-J", "I-G-T-C-V",
"U-D-T-B-F", "N-Q-X-R-V", "F-O-N-L-V",
"R-C-X-F-I", "C-G-H-U-X", "T-I-J-W-G",
"U-B-G-O-Y", "G-C-H-Q-V", "S-U-D-A-H",
"F-B-S-I-H", "X-R-S-O-B", "M-H-C-E-K",
"Y-J-A-T-N", "Z-B-I-D-X", "R-I-U-E-B",
"C-S-O-V-X", "S-Y-G-E-M", "N-O-D-H-Z",
"U-D-V-T-S", "U-I-H-Q-M", "L-E-S-U-Y",
"L-Q-Y-W-P", "J-K-U-C-V", "A-Z-R-S-N",
"Z-F-A-Y-L", "C-L-G-R-I", "A-N-Q-C-Z",
"A-X-P-R-Z", "W-N-I-M-X", "O-I-L-B-N",
"P-U-Q-S-Y", "N-M-W-L-D", "D-V-X-C-R",
"P-G-J-I-X", "Y-G-C-T-H", "R-S-V-N-X",
"Y-H-O-Q-D", "Q-N-Y-Z-H", "D-Q-J-B-H",
"N-X-O-Z-T", "R-Q-B-X-J", "V-S-U-E-K",
"H-X-U-C-K", "W-X-E-I-P", "Z-H-J-N-L",
"A-R-N-V-H", "R-W-L-O-N", "Q-Z-K-E-G",
"M-X-L-W-F", "Z-R-L-K-J", "S-E-G-Y-N",
"R-H-K-V-L", "A-V-Q-R-I", "Z-L-J-B-O",
"W-S-R-C-V", "S-L-Q-M-R", "T-P-Y-A-K",
"W-R-H-U-O", "Z-B-Q-P-J", "I-H-Q-Y-U",
"W-K-U-I-S", "V-Y-N-M-W", "O-C-P-J-V",
"M-S-Z-W-G", "T-M-E-X-F", "E-W-A-P-N",
"Z-S-N-B-K", "G-D-X-R-V", "O-D-J-X-I",
"F-V-G-U-L", "R-U-I-Z-M", "G-E-O-L-I",
"K-T-B-F-X", "I-M-R-C-T", "B-Q-M-F-C",
"E-J-F-W-B", "W-P-N-H-G", "E-F-G-O-J",
"P-C-O-S-H", "C-L-A-N-W", "J-N-B-F-K",
"S-X-A-E-Z", "G-B-F-T-P", "K-C-G-D-E",
"T-I-O-G-U", "B-R-W-Q-Z", "L-C-R-G-N",
"F-A-B-V-G", "R-E-Q-W-L", "L-Z-J-H-S",
"E-R-L-D-N", "N-D-A-O-F", "V-O-A-C-L",
"A-J-S-M-W", "K-B-V-T-O", "J-D-P-K-L",
"J-Y-T-D-X", "Z-A-E-K-B", "L-D-R-Z-Q",
"O-X-L-B-G", "B-P-V-O-K", "Y-J-D-T-E",
"C-F-R-N-W", "U-Y-M-Q-E", "Y-O-V-X-H",
"Z-K-D-V-Q", "A-Q-B-P-S", "W-S-O-Z-B",
"W-D-U-F-S", "A-H-P-R-E", "W-N-V-J-K",
"D-F-U-Y-S", "O-A-G-P-V", "V-J-R-E-P",
"I-P-R-E-U", "F-T-C-O-G", "K-F-U-M-H",
"V-N-F-X-U", "E-R-C-H-B", "D-U-C-V-X",
"Q-Z-U-C-A", "B-G-I-O-T", "L-C-S-Z-M",
"S-Y-A-W-P", "K-M-D-G-N", "O-I-D-R-Q",
"D-P-J-Q-C", "T-N-I-B-L", "I-G-M-D-A",
"O-D-C-L-Y", "B-D-Q-H-F", "H-M-W-P-X",
"Z-Q-U-T-L", "K-F-I-O-R", "U-W-L-M-V",
"M-A-N-D-Y", "M-E-X-I-K", "Y-S-F-L-V",
"Q-Y-O-L-E", "T-K-G-A-O", "I-S-J-V-Q",
"J-K-P-B-G", "D-P-F-I-T", "I-Q-B-J-M",
"E-Q-H-V-W", "J-D-C-E-Q", "Q-U-V-D-J",
"G-D-S-Z-T", "U-M-X-Z-C", "Q-R-Z-G-W",
"R-C-L-Q-J", "E-I-O-V-W", "S-E-R-D-Q",
"V-J-E-D-T", "K-A-D-N-T", "P-C-R-Z-X",
"P-B-I-T-E", "H-W-Q-L-C", "C-J-K-E-G",
"R-Y-D-P-Q", "R-X-U-L-K", "R-T-Q-G-Y",
"X-H-J-T-D", "U-E-F-I-A", "L-K-O-C-M",
"K-Y-H-M-J", "T-M-K-L-Y", "B-D-U-L-P",
"D-G-N-F-H", "H-K-O-J-B", "L-A-C-X-D",
"L-D-P-Q-J", "A-F-T-U-R", "M-W-H-Q-V",
"T-F-J-S-G", "C-T-W-E-N", "K-U-F-A-D",
"S-U-Q-T-P", "K-V-Y-B-T", "E-V-Y-O-S",
"D-J-E-I-C", "Y-P-M-X-O", "Q-X-W-K-S",
"G-W-O-B-C", "A-V-G-B-D", "I-L-V-D-K",
"R-V-G-B-W", "Z-S-O-M-G", "B-A-C-X-W",
"S-P-X-G-Q", "A-I-S-C-B", "Q-N-S-J-P",
"E-T-W-J-B", "R-X-Y-T-E", "X-G-Z-V-S",
"C-M-B-A-N", "N-L-W-B-I", "R-H-E-F-X",
"E-U-I-Z-C", "N-F-E-Z-V", "T-S-O-J-F",
"R-U-B-S-K", "R-A-S-K-G", "O-F-K-R-V",
"N-X-J-A-M", "E-A-Z-T-X", "H-G-S-J-M",
"H-E-A-J-U", "N-Z-M-Q-O", "B-M-R-E-S",
"X-Y-Z-E-U", "W-I-H-R-J", "N-W-M-Y-Q",
"I-N-O-T-P", "C-N-T-H-W", "O-C-M-H-L",
"V-U-X-N-Q", "M-B-W-A-N", "H-Q-Z-B-L",
"H-E-C-O-Y", "A-D-W-F-Y", "C-G-L-M-O",
"A-D-U-O-C", "U-O-V-R-H", "Z-B-Y-G-L",
"L-X-C-E-P", "L-P-K-M-R", "A-F-T-M-B",
"E-Z-B-K-U", "D-F-E-A-Y", "J-A-R-M-O",
"T-N-I-U-X", "F-Q-B-D-J", "N-J-M-R-Z",
"Z-G-C-A-K", "U-G-V-X-H", "D-I-R-Z-W",
"E-O-M-R-T", "L-G-S-F-M", "A-J-C-K-N",
"Z-N-D-L-H", "X-Y-S-U-V", "B-Q-I-L-Y",
"J-C-D-Z-E", "S-U-K-T-G", "P-W-T-X-U",
"D-I-H-B-A", "Y-W-L-U-E", "F-O-A-S-V",
"B-H-R-Z-J", "B-V-C-Y-L", "Z-C-J-F-H",
"Z-Y-V-A-T", "R-F-D-E-Y", "J-O-L-A-M",
"L-B-Z-F-P", "X-P-S-D-R", "O-E-B-R-S",
"J-P-B-Q-X", "Q-E-Z-I-U", "Q-N-G-U-P",
"W-O-L-I-T", "D-O-B-K-Z", "Z-E-A-V-J",
"K-D-E-W-A", "Y-B-M-C-Z", "B-N-Y-J-O",
"L-U-F-E-J", "B-V-X-O-F", "V-X-S-A-P",
"L-B-Y-D-E", "E-U-D-V-T", "J-P-T-D-A",
"Q-C-R-X-V", "I-D-L-A-O", "R-G-Q-V-K",
"H-S-W-R-F", "C-E-F-Y-O", "S-P-B-Q-M",
"B-J-Z-F-Q", "U-E-C-P-Z", "D-H-O-E-B",
"G-J-L-R-S", "L-C-V-T-S", "R-V-W-K-I",
"A-M-X-W-P", "W-B-K-A-C", "P-O-I-L-S",
"A-K-T-B-Y", "K-B-X-R-T", "S-P-T-Q-W",
"D-Z-U-W-B", "L-S-E-H-Q", "G-F-W-U-N",
"J-T-E-Z-F", "V-X-N-T-B", "T-K-D-N-R",
"L-K-Q-I-T", "N-E-X-D-Q", "Y-B-S-X-A",
"S-D-W-J-Q", "U-H-J-W-I", "X-Z-A-J-B",
"E-S-D-O-H", "G-O-Y-N-Q", "U-F-I-B-A",
"M-H-W-C-O", "F-Z-C-B-M", "S-C-A-O-V",
"G-R-H-Q-U", "V-N-J-Q-P", "V-P-Y-M-U",
"R-J-O-Q-V", "G-C-U-E-I", "C-A-T-L-R",
"O-N-S-G-H", "P-Z-K-U-V", "R-Z-H-D-N",
"G-E-X-C-L", "Q-K-E-P-S", "N-K-I-H-A",
"A-N-T-R-M", "T-R-G-E-F", "I-B-T-S-D",
"G-R-J-L-W", "I-P-Y-K-L", "S-J-M-F-W",
"U-H-D-P-T", "A-D-H-M-B", "S-T-Z-P-U",
"N-I-G-R-S", "U-V-M-Q-S", "E-F-S-J-R",
"F-H-O-S-Z", "O-G-R-E-Z", "B-M-A-N-T",
"Z-H-D-L-Q", "Q-R-N-J-K", "C-X-H-Y-L",
"I-X-W-G-E", "T-B-M-Q-S", "A-H-Z-V-B",
"R-Z-M-X-G", "M-U-K-H-E", "G-B-L-A-W",
"R-X-T-S-F", "D-W-Q-M-S", "P-B-F-Q-K",
"R-H-I-J-V", "I-F-J-V-C", "U-T-K-R-F",
"P-T-L-U-R", "I-L-P-N-F", "D-H-K-X-J",
"A-Q-B-M-S", "B-V-L-Q-F", "C-H-K-V-A",
"T-Y-C-P-U", "B-U-P-Q-H", "M-H-Q-E-I",
"E-Z-S-U-K", "H-W-Q-R-M", "C-I-B-J-K",
"E-I-O-S-H", "Y-I-E-X-L", "S-Q-O-L-N",
"J-H-L-T-G", "H-M-Q-J-I", "V-I-Z-J-Q",
"B-G-R-J-P", "Z-I-W-B-O", "R-V-B-G-N",
"B-I-N-J-R", "F-T-W-M-L", "F-S-K-I-J",
"S-N-V-G-Z", "X-I-G-L-H", "K-B-X-V-A",
"F-M-A-H-N", "Y-Z-I-W-A", "P-M-R-C-Z",
"N-U-B-R-A", "wordZ2", "Var1",
"Var2", "Var3", "Var4",
"a", "b", "c",
"e", "f", "h",
"i", "Var5", "Var6",
"Var7", "col 1", "col 2", "g", "x"
), uniqueCount = "2114")
}
#' provides testfile path for testthat
#' @param x a file assumed in testfiles folder
testfile_path <- function(x, replace = FALSE) {
test_path <- testthat::test_path("testfiles")
if (!dir.exists(test_path)) {
dir.create(test_path)
}
fl <- testthat::test_path("testfiles", x)
if (Sys.getenv("openxlsx2_testthat_fullrun") == "") {
if (isTRUE(as.logical(Sys.getenv("CI", "false")))) # on_ci()
return(testthat::skip("Skip on CI"))
if (!interactive() && !isTRUE(as.logical(Sys.getenv("NOT_CRAN", "false")))) # on_cran()
return(testthat::skip("Skip on CRAN"))
}
# try to download
if (!file.exists(fl) || replace) {
out <- paste0(test_path, "/", x)
url <- paste0("https://github.com/JanMarvin/openxlsx-data/raw/main/", x)
try({
download.file(url, destfile = out, quiet = TRUE, mode = "wb")
})
}
if (!file.exists(fl)) {
return(testthat::skip("Testfile does not exist"))
}
fl
}
testsetup <- function() {
if (is.null(getOption("openxlsx2.datetimeCreated"))) {
testthat::test_that("testsetup", {
options("openxlsx2.datetimeCreated" = as.POSIXct("2023-07-20 23:32:14", tz = "UTC"))
wb <- wb_workbook()
exp <- "2023-07-20T23:32:14Z"
got <- wb$get_properties()[["datetime_created"]]
testthat::expect_equal(exp, got)
})
}
}
# testthat::skip_if_offline requires curl, but fails if curl is not available
skip_online_checks <- function() {
testthat::skip_on_cran()
testthat::skip_if_not_installed("curl")
testthat::skip_if_offline()
}