Nothing
box::use(
testthat[expect_equal, expect_false, expect_true, test_that]
)
box::use(
artma / options / column_preprocessing[preprocess_column_mapping]
)
# Helper to create a mock options_def structure
create_mock_options_def <- function() {
list(
list(
name = "data.source_path",
type = "character",
allow_na = FALSE
),
list(
name = "data.config_setup",
type = "enum",
allow_na = FALSE
),
list(
name = "data.columns",
type = "list",
allow_na = TRUE
)
)
}
# Helper to create a temp CSV file
create_temp_csv_file <- function() {
csv_content <- c(
"study_name;effect;se;n_obs",
"Study A;10.5;2.3;100",
"Study B;8.2;1.8;150"
)
tmp_file <- tempfile(fileext = ".csv")
writeLines(csv_content, tmp_file)
tmp_file
}
# When there is nothing to auto-detect (no source path, NA/empty path, or a
# path that does not resolve to a file), the mapping is returned unchanged.
test_that("preprocess_column_mapping returns input unchanged when there is nothing to auto-detect", {
options_def <- create_mock_options_def()
withr::local_options(list("artma.verbose" = 1))
cases <- list(
"no data.source_path" = list("verbose" = 3),
"data.source_path is NA" = list("data.source_path" = NA),
"data.source_path is empty string" = list("data.source_path" = ""),
"file does not exist" = list("data.source_path" = "/nonexistent/path/to/file.csv")
)
for (label in names(cases)) {
user_input <- cases[[label]]
expect_equal(
preprocess_column_mapping(user_input, options_def),
user_input,
info = label
)
}
})
test_that("preprocess_column_mapping returns unchanged when config_setup is manual", {
tmp_file <- create_temp_csv_file()
on.exit(unlink(tmp_file))
user_input <- list(
"data.source_path" = tmp_file,
"data.config_setup" = "manual"
)
options_def <- create_mock_options_def()
withr::local_options(list("artma.verbose" = 1))
result <- preprocess_column_mapping(user_input, options_def)
# Should not add column records when manual mode
expect_false("data.columns" %in% names(result))
})
test_that("preprocess_column_mapping returns unchanged when the column store is already specified", {
tmp_file <- create_temp_csv_file()
on.exit(unlink(tmp_file))
provided_columns <- list(
study_id = list(source_name = "study_name"),
effect = list(source_name = "effect"),
se = list(source_name = "se"),
n_obs = list(source_name = "n_obs")
)
user_input <- list(
"data.source_path" = tmp_file,
"data.columns" = provided_columns
)
options_def <- create_mock_options_def()
withr::local_options(list("artma.verbose" = 1))
result <- preprocess_column_mapping(user_input, options_def)
# Should keep the provided store unchanged
expect_equal(result$data.columns, provided_columns)
})
test_that("preprocess_column_mapping adds auto-detected columns when missing", {
tmp_file <- create_temp_csv_file()
on.exit(unlink(tmp_file))
user_input <- list(
"data.source_path" = tmp_file,
"data.config_setup" = "auto"
)
options_def <- create_mock_options_def()
withr::local_options(list("artma.verbose" = 3))
result <- preprocess_column_mapping(user_input, options_def)
# Should have added auto-detected role records to the unified store.
# Only genuine renames are stored; columns already carrying the standard
# name (effect, se, n_obs) need no record.
records <- result$data.columns
expect_true(is.list(records))
expect_equal(records$study_id$source_name, "study_name")
expect_false("effect" %in% names(records))
expect_false("se" %in% names(records))
expect_false("n_obs" %in% names(records))
})
test_that("preprocess_column_mapping does not override a user-supplied column store", {
tmp_file <- create_temp_csv_file()
on.exit(unlink(tmp_file))
user_input <- list(
"data.source_path" = tmp_file,
"data.columns" = list(
study_id = list(source_name = "my_custom_study_col")
)
)
options_def <- create_mock_options_def()
withr::local_options(list("artma.verbose" = 1))
result <- preprocess_column_mapping(user_input, options_def)
# Should preserve the user's store as-is
expect_equal(
result$data.columns,
list(study_id = list(source_name = "my_custom_study_col"))
)
})
test_that("preprocess_column_mapping handles errors gracefully", {
# Create a malformed CSV
tmp_file <- tempfile(fileext = ".csv")
writeLines("not,a,valid,csv\n{{{{malformed", tmp_file)
on.exit(unlink(tmp_file))
user_input <- list(
"data.source_path" = tmp_file
)
options_def <- create_mock_options_def()
withr::local_options(list("artma.verbose" = 1))
# Should not error, just return original input
result <- preprocess_column_mapping(user_input, options_def)
# Should not have added column records due to error
expect_false("data.columns" %in% names(result))
})
test_that("preprocess_column_mapping works with comma-delimited files", {
csv_content <- c(
"study_name,effect,se,n_obs",
"Study A,10.5,2.3,100",
"Study B,8.2,1.8,150"
)
tmp_file <- tempfile(fileext = ".csv")
writeLines(csv_content, tmp_file)
on.exit(unlink(tmp_file))
user_input <- list(
"data.source_path" = tmp_file
)
options_def <- create_mock_options_def()
withr::local_options(list("artma.verbose" = 1))
result <- preprocess_column_mapping(user_input, options_def)
# Should detect columns regardless of delimiter
expect_true("study_id" %in% names(result$data.columns))
expect_equal(result$data.columns$study_id$source_name, "study_name")
})
test_that("preprocess_column_mapping detects columns in a Latin-1 encoded file", {
# Regression: a citation-style study label carrying a raw 0xFC byte ("Müller"
# in Windows-1252) made is_likely_study_key()'s character-class regexes error
# out, the whole detection step was swallowed by the surrounding tryCatch,
# and the options file was written with no mapping at all. Encoding is now
# repaired at the read boundary, so detection runs normally.
tmp_file <- tempfile(fileext = ".csv")
con <- file(tmp_file, open = "wb")
writeBin(charToRaw(paste0(paste(c(
"study_name,effect,standard_error,sample_size",
"M\xfcller et al. (2011),0.5,0.1,100",
"Smith (2015),0.7,0.2,150",
"Jones (2019),0.3,0.05,220"
), collapse = "\n"), "\n")), con)
close(con)
on.exit(unlink(tmp_file))
user_input <- list("data.source_path" = tmp_file)
options_def <- create_mock_options_def()
withr::local_options(list("artma.verbose" = 1))
result <- preprocess_column_mapping(user_input, options_def)
expect_equal(result$data.columns$study_id$source_name, "study_name")
expect_equal(result$data.columns$se$source_name, "standard_error")
expect_equal(result$data.columns$n_obs$source_name, "sample_size")
})
test_that("preprocess_column_mapping does not guess a mapping for an undetectable required column", {
# n_obs is required but absent from the data. In a non-interactive session
# (such as this test run) the flow must leave it unmapped rather than fall
# back to climenu's first menu entry, which used to record
# n_obs: source_name: effect.
csv_content <- c(
"effect,se,study_id",
"0.5,0.1,Study A",
"0.7,0.2,Study B"
)
tmp_file <- tempfile(fileext = ".csv")
writeLines(csv_content, tmp_file)
on.exit(unlink(tmp_file))
user_input <- list("data.source_path" = tmp_file)
options_def <- create_mock_options_def()
withr::local_options(list("artma.verbose" = 1))
result <- preprocess_column_mapping(user_input, options_def)
expect_false("n_obs" %in% names(result$data.columns))
})
test_that("non-interactive options_create leaves an undetectable required column unmapped", {
box::use(
artma / options / files[options_file_path, read_options_file]
)
csv_content <- c(
"effect,se,study_id",
"0.5,0.1,Study A",
"0.7,0.2,Study B"
)
tmp_file <- tempfile(fileext = ".csv")
writeLines(csv_content, tmp_file)
on.exit(unlink(tmp_file))
tmp_dir <- withr::local_tempdir()
file_name <- "missing-nobs.yaml"
withr::local_options(list("artma.verbose" = 1))
artma::options_create(
options_file_name = file_name,
options_dir = tmp_dir,
user_input = list("data.source_path" = tmp_file),
should_validate = FALSE,
should_overwrite = TRUE
)
written <- read_options_file(options_file_path(tmp_dir, file_name))
columns <- written$data$columns
# With nothing to record, the columns node stays empty (read back as NA).
# The menu-default fallback used to record n_obs: source_name: effect here,
# which made the next run rename effect to n_obs and abort.
expect_false(is.list(columns) && "n_obs" %in% names(columns))
})
test_that("preprocess_column_mapping respects verbosity settings", {
tmp_file <- create_temp_csv_file()
on.exit(unlink(tmp_file))
user_input <- list(
"data.source_path" = tmp_file
)
options_def <- create_mock_options_def()
# Test with verbose = 1 (should not output much)
withr::local_options(list("artma.verbose" = 1))
result1 <- preprocess_column_mapping(user_input, options_def)
# Test with verbose = 3 (should output info messages)
withr::local_options(list("artma.verbose" = 3))
result2 <- preprocess_column_mapping(user_input, options_def)
# Both should produce the same result
expect_equal(result1, result2)
expect_true("study_id" %in% names(result1$data.columns))
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.