Nothing
# =============================================================================
# Tests for pre_calibrated parameter (TSQCA v1.3.0)
# =============================================================================
# Test coverage:
# [BC] Backward compatibility — pre_calibrated = NULL produces v1.2.0 output
# [T] Functional tests — T-01 through T-06 from design spec
# [V] Validation tests — V-01 through V-04 from design spec
# [C] Consistency test — manual binarization equivalence
# [E] extract_mode="essential" x pre_calibrated (confirmation item 2)
# =============================================================================
# ---------------------------------------------------------------------------
# Helper: build test data with one pre-calibrated (fuzzy) column
# ---------------------------------------------------------------------------
make_test_dat <- function() {
data("sample_data", package = "TSQCA")
dat <- sample_data
# X2_fuzzy: manually fuzzy-calibrate X2 (range ~1-10) into [0,1]
# simple linear rescale so values stay in [0,1]
x2_raw <- dat$X2
dat$X2_fuzzy <- (x2_raw - min(x2_raw)) / (max(x2_raw) - min(x2_raw))
# X3_bin: hard binary (already 0/1-like after threshold)
dat$X3_bin <- ifelse(dat$X3 >= 7, 1L, 0L)
dat
}
# =============================================================================
# [BC] Backward Compatibility Tests
# =============================================================================
test_that("[BC] otSweep: pre_calibrated=NULL produces identical output to v1.2.0", {
data("sample_data", package = "TSQCA")
dat <- sample_data
thrX <- c(X1 = 7, X2 = 7, X3 = 7)
res_default <- otSweep(
dat = dat, outcome = "Y", conditions = c("X1", "X2", "X3"),
sweep_range = 6:8, thrX = thrX, return_details = FALSE
)
res_null <- otSweep(
dat = dat, outcome = "Y", conditions = c("X1", "X2", "X3"),
sweep_range = 6:8, thrX = thrX,
pre_calibrated = NULL, return_details = FALSE
)
expect_equal(res_default, res_null)
})
test_that("[BC] dtSweep: pre_calibrated=NULL produces identical output to v1.2.0", {
data("sample_data", package = "TSQCA")
dat <- sample_data
res_default <- dtSweep(
dat = dat, outcome = "Y", conditions = c("X1", "X2", "X3"),
sweep_list_X = list(X1 = 6:7, X2 = 7, X3 = 7),
sweep_range_Y = 6:7, return_details = FALSE
)
res_null <- dtSweep(
dat = dat, outcome = "Y", conditions = c("X1", "X2", "X3"),
sweep_list_X = list(X1 = 6:7, X2 = 7, X3 = 7),
sweep_range_Y = 6:7,
pre_calibrated = NULL, return_details = FALSE
)
expect_equal(res_default, res_null)
})
test_that("[BC] ctSweepS: pre_calibrated=NULL produces identical output to v1.2.0", {
data("sample_data", package = "TSQCA")
dat <- sample_data
res_default <- ctSweepS(
dat = dat, outcome = "Y", conditions = c("X1", "X2", "X3"),
sweep_var = "X3", sweep_range = 6:8, thrY = 7, thrX_default = 7,
return_details = FALSE
)
res_null <- ctSweepS(
dat = dat, outcome = "Y", conditions = c("X1", "X2", "X3"),
sweep_var = "X3", sweep_range = 6:8, thrY = 7, thrX_default = 7,
pre_calibrated = NULL, return_details = FALSE
)
expect_equal(res_default, res_null)
})
test_that("[BC] ctSweepM: pre_calibrated=NULL produces identical output to v1.2.0", {
data("sample_data", package = "TSQCA")
dat <- sample_data
res_default <- ctSweepM(
dat = dat, outcome = "Y", conditions = c("X1", "X2", "X3"),
sweep_list = list(X1 = 6:7, X2 = 7, X3 = 7),
thrY = 7, return_details = FALSE
)
res_null <- ctSweepM(
dat = dat, outcome = "Y", conditions = c("X1", "X2", "X3"),
sweep_list = list(X1 = 6:7, X2 = 7, X3 = 7),
thrY = 7, pre_calibrated = NULL, return_details = FALSE
)
expect_equal(res_default, res_null)
})
# =============================================================================
# [T] Functional Tests (T-01 to T-06)
# =============================================================================
test_that("[T-01] otSweep: single fuzzy condition runs and returns valid output", {
dat <- make_test_dat()
res <- otSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2_fuzzy = 0.5, X3 = 7),
pre_calibrated = c("X2_fuzzy"),
return_details = TRUE
)
expect_s3_class(res, "otSweep_result")
expect_true(nrow(res$summary) > 0)
expect_true(all(c("expression", "inclS", "covS") %in% names(res$summary)))
# pre_calibrated stored in params
expect_equal(res$params$pre_calibrated, c("X2_fuzzy"))
})
test_that("[T-01] otSweep: fuzzy condition produces different result from crisp binarization", {
dat <- make_test_dat()
thrX_crisp <- c(X1 = 7, X2 = 7, X3 = 7)
thrX_fuzzy <- c(X1 = 7, X2_fuzzy = 0.5, X3 = 7)
res_crisp <- otSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_range = 6:8, thrX = thrX_crisp, return_details = FALSE
)
res_fuzzy <- otSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_range = 6:8, thrX = thrX_fuzzy,
pre_calibrated = c("X2_fuzzy"), return_details = FALSE
)
# Results should differ because X2_fuzzy retains graded membership
# (at least one expression or fit metric will differ)
expect_false(identical(res_crisp$expression, res_fuzzy$expression) &&
identical(res_crisp$inclS, res_fuzzy$inclS) &&
identical(res_crisp$covS, res_fuzzy$covS))
})
test_that("[T-02] otSweep: all conditions fuzzy runs without error", {
dat <- make_test_dat()
dat$X1_fuzzy <- (dat$X1 - min(dat$X1)) / (max(dat$X1) - min(dat$X1))
res <- otSweep(
dat = dat, outcome = "Y",
conditions = c("X1_fuzzy", "X2_fuzzy", "X3_bin"),
sweep_range = 6:8,
thrX = c(X1_fuzzy = 0.5, X2_fuzzy = 0.5, X3_bin = 1),
pre_calibrated = c("X1_fuzzy", "X2_fuzzy", "X3_bin"),
return_details = FALSE
)
expect_s3_class(res, "data.frame")
expect_true(nrow(res) > 0)
})
test_that("[T-03] dtSweep: mixed fuzzy/crisp conditions run without error", {
dat <- make_test_dat()
res <- dtSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_list_X = list(X1 = 6:7, X2_fuzzy = 0.5, X3 = 7),
sweep_range_Y = 6:7,
pre_calibrated = c("X2_fuzzy"),
return_details = FALSE
)
expect_s3_class(res, "data.frame")
expect_true(nrow(res) > 0)
})
test_that("[T-04] ctSweepS: pre_calibrated non-swept conditions pass through", {
dat <- make_test_dat()
res <- ctSweepS(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_var = "X1",
sweep_range = 6:8,
thrY = 7, thrX_default = 7,
pre_calibrated = c("X2_fuzzy"),
return_details = TRUE
)
expect_s3_class(res, "ctSweepS_result")
expect_true(nrow(res$summary) > 0)
expect_equal(res$params$pre_calibrated, c("X2_fuzzy"))
})
test_that("[T-05] ctSweepM: pre_calibrated non-swept conditions pass through", {
dat <- make_test_dat()
res <- ctSweepM(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_list = list(X1 = 6:7, X2_fuzzy = 0.5, X3 = 7),
thrY = 7,
pre_calibrated = c("X2_fuzzy"),
return_details = TRUE
)
expect_s3_class(res, "ctSweepM_result")
expect_true(nrow(res$summary) > 0)
expect_equal(res$params$pre_calibrated, c("X2_fuzzy"))
})
test_that("[T-06] Binary variable as pre_calibrated passes through unchanged", {
dat <- make_test_dat()
# X3_bin is already 0/1 — using pre_calibrated should give same result as
# binarizing with thrX = 1
res_pc <- otSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2", "X3_bin"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2 = 7, X3_bin = 1),
pre_calibrated = c("X3_bin"),
return_details = FALSE
)
res_thr <- otSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2", "X3_bin"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2 = 7, X3_bin = 1),
return_details = FALSE
)
expect_equal(res_pc$expression, res_thr$expression)
expect_equal(res_pc$inclS, res_thr$inclS)
expect_equal(res_pc$covS, res_thr$covS)
})
# =============================================================================
# [V] Validation Tests (V-01 to V-04)
# =============================================================================
test_that("[V-01] Error when pre_calibrated variable not in conditions", {
data("sample_data", package = "TSQCA")
dat <- sample_data
expect_error(
otSweep(
dat = dat, outcome = "Y", conditions = c("X1", "X2", "X3"),
sweep_range = 6:8, thrX = c(X1 = 7, X2 = 7, X3 = 7),
pre_calibrated = c("X99")
),
regexp = "not found in conditions"
)
})
test_that("[V-02] Error when pre_calibrated variable has values outside [0, 1]", {
data("sample_data", package = "TSQCA")
dat <- sample_data # X1 has raw Likert values (e.g., 1-10)
expect_error(
otSweep(
dat = dat, outcome = "Y", conditions = c("X1", "X2", "X3"),
sweep_range = 6:8, thrX = c(X1 = 7, X2 = 7, X3 = 7),
pre_calibrated = c("X1") # X1 is raw scale, not [0,1]
),
regexp = "outside \\[0, 1\\]"
)
})
test_that("[V-03] Warning when pre_calibrated variable contains NA", {
dat <- make_test_dat()
dat$X2_fuzzy[1] <- NA # inject NA
expect_warning(
otSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2_fuzzy = 0.5, X3 = 7),
pre_calibrated = c("X2_fuzzy")
),
regexp = "contains NA"
)
})
test_that("[V-04] Warning when pre_calibrated variable is also a sweep target in dtSweep", {
dat <- make_test_dat()
expect_warning(
dtSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_list_X = list(X1 = 6:7, X2_fuzzy = c(0.3, 0.5, 0.7), X3 = 7),
sweep_range_Y = 6:7,
pre_calibrated = c("X2_fuzzy")
),
regexp = "sweep thresholds ignored"
)
})
test_that("[V-04] Warning when pre_calibrated variable is also a sweep target in ctSweepM", {
dat <- make_test_dat()
expect_warning(
ctSweepM(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_list = list(X1 = 6:7, X2_fuzzy = c(0.3, 0.5, 0.7), X3 = 7),
thrY = 7,
pre_calibrated = c("X2_fuzzy")
),
regexp = "sweep thresholds ignored"
)
})
# =============================================================================
# [C] Consistency Test — manual binarization equivalence
# =============================================================================
test_that("[C] Manual binarization at 0.5 equals pre_calibrated=NULL with thrX=0.5", {
dat <- make_test_dat()
# Method A: pass fuzzy values, let qca_bin() binarize at 0.5 (default behavior)
res_a <- otSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2_fuzzy = 0.5, X3 = 7),
pre_calibrated = NULL, # binarize X2_fuzzy at 0.5
return_details = FALSE
)
# Method B: manually binarize X2_fuzzy at 0.5 before passing
dat_b <- dat
dat_b$X2_fuzzy <- ifelse(dat$X2_fuzzy >= 0.5, 1L, 0L)
res_b <- otSweep(
dat = dat_b, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2_fuzzy = 1, X3 = 7),
pre_calibrated = c("X2_fuzzy"), # already 0/1, pass through
return_details = FALSE
)
expect_equal(res_a$expression, res_b$expression)
expect_equal(res_a$inclS, res_b$inclS, tolerance = 1e-10)
expect_equal(res_a$covS, res_b$covS, tolerance = 1e-10)
})
# =============================================================================
# [E] extract_mode="essential" x pre_calibrated (confirmation item 2)
# =============================================================================
test_that("[E] extract_mode='essential' works with pre_calibrated fuzzy condition", {
dat <- make_test_dat()
res <- otSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2_fuzzy = 0.5, X3 = 7),
pre_calibrated = c("X2_fuzzy"),
extract_mode = "essential",
return_details = TRUE
)
expect_s3_class(res, "otSweep_result")
expect_true("n_solutions" %in% names(res$summary))
# expression column must exist and be character (EPI or "No essential prime implicants")
expect_true(is.character(res$summary$expression))
})
test_that("[E] extract_mode='all' works with pre_calibrated fuzzy condition", {
dat <- make_test_dat()
res <- otSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2_fuzzy = 0.5, X3 = 7),
pre_calibrated = c("X2_fuzzy"),
extract_mode = "all",
return_details = TRUE
)
expect_s3_class(res, "otSweep_result")
expect_true("n_solutions" %in% names(res$summary))
})
test_that("[E] EPI identification unaffected by variable being fuzzy vs crisp", {
dat <- make_test_dat()
# essential mode with pre_calibrated fuzzy variable
res_fuzzy <- otSweep(
dat = dat, outcome = "Y",
conditions = c("X1", "X2_fuzzy", "X3"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2_fuzzy = 0.5, X3 = 7),
pre_calibrated = c("X2_fuzzy"),
extract_mode = "essential",
return_details = FALSE
)
# expression column must not be NA for all rows
non_na_count <- sum(!is.na(res_fuzzy$expression))
expect_true(non_na_count > 0)
# selective_terms and unique_terms columns must exist
expect_true("selective_terms" %in% names(res_fuzzy))
expect_true("unique_terms" %in% names(res_fuzzy))
})
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.