Nothing
# Test Suite for S3 Methods of gkwreg Objects
# Author: Lopes, J. E.
# Description: Comprehensive tests covering all S3 methods: print, coef, summary,
# print.summary, vcov, nobs, and confint for gkwreg objects
library(testthat)
library(gkwreg)
library(gkwdist)
# Setup: Generate test data and fit model
setup_methods_data <- function() {
set.seed(47856)
n <- 120
x1 <- rnorm(n)
x2 <- runif(n, -1, 1)
x3 <- factor(sample(c("A", "B"), n, replace = TRUE))
# Generate Kumaraswamy response
alpha <- exp(0.65 + 0.28 * x1)
beta <- exp(1.15 - 0.18 * x2)
y <- rkw(n, alpha = alpha, beta = beta)
# Ensure strictly in (0, 1)
y <- pmax(pmin(y, 1 - 1e-10), 1e-10)
data <- data.frame(y = y, x1 = x1, x2 = x2, x3 = x3)
# Fit model with Hessian
fit <- gkwreg(y ~ x1 | x2,
data = data, family = "kw",
control = gkw_control(hessian = TRUE)
)
list(data = data, fit = fit, y = y)
}
# =============================================================================
# TESTS FOR print.gkwreg (3 tests)
# =============================================================================
test_that("Test 1: print.gkwreg produces output without errors", {
# Test that print method executes successfully
setup <- setup_methods_data()
expect_output(print(setup$fit), regexp = "Call")
expect_output(print(setup$fit), regexp = "Coefficients")
})
test_that("Test 2: print.gkwreg respects digits argument", {
# Test that digits parameter controls output precision
setup <- setup_methods_data()
# Should work with different digit specifications
expect_no_error(print(setup$fit, digits = 2))
expect_no_error(print(setup$fit, digits = 5))
expect_no_error(print(setup$fit, digits = 8))
})
test_that("Test 3: print.gkwreg returns object invisibly", {
# Test that print returns the object invisibly
setup <- setup_methods_data()
result <- withVisible(print(setup$fit))
expect_false(result$visible)
expect_identical(result$value, setup$fit)
expect_s3_class(result$value, "gkwreg")
})
# =============================================================================
# TESTS FOR coef.gkwreg (2 tests)
# =============================================================================
test_that("Test 4: coef.gkwreg extracts coefficients correctly", {
# Test that coef method returns named numeric vector
setup <- setup_methods_data()
coefs <- coef(setup$fit)
expect_type(coefs, "double")
expect_true(is.numeric(coefs))
expect_true(!is.null(names(coefs)))
expect_true(all(is.finite(coefs)))
# Should have coefficients for both parameters
expect_true(any(grepl("alpha", names(coefs))))
expect_true(any(grepl("beta", names(coefs))))
})
test_that("Test 5: coef.gkwreg matches stored coefficients component", {
# Test that coef() returns same as direct access
setup <- setup_methods_data()
coefs_method <- coef(setup$fit)
coefs_direct <- setup$fit$coefficients
expect_identical(coefs_method, coefs_direct)
expect_equal(length(coefs_method), setup$fit$npar)
})
# =============================================================================
# TESTS FOR summary.gkwreg (4 tests)
# =============================================================================
test_that("Test 6: summary.gkwreg returns proper summary object", {
# Test that summary method creates summary.gkwreg object
setup <- setup_methods_data()
summ <- summary(setup$fit)
expect_s3_class(summ, "summary.gkwreg")
expect_type(summ, "list")
# Check essential components
expect_true("call" %in% names(summ))
expect_true("family" %in% names(summ))
expect_true("coefficients" %in% names(summ))
expect_true("link" %in% names(summ))
})
test_that("Test 7: summary.gkwreg computes z-values and p-values", {
# Test that summary calculates test statistics
setup <- setup_methods_data()
summ <- summary(setup$fit)
coef_table <- summ$coefficients
expect_true("Estimate" %in% colnames(coef_table))
expect_true("Std. Error" %in% colnames(coef_table))
expect_true("z value" %in% colnames(coef_table))
expect_true("Pr(>|z|)" %in% colnames(coef_table))
# All p-values should be between 0 and 1
p_vals <- coef_table[, "Pr(>|z|)"]
expect_true(all(p_vals >= 0 & p_vals <= 1))
})
test_that("Test 8: summary.gkwreg computes confidence intervals", {
# Test that confidence intervals are calculated
setup <- setup_methods_data()
summ_95 <- summary(setup$fit, conf.level = 0.95)
summ_90 <- summary(setup$fit, conf.level = 0.90)
expect_true(!is.null(summ_95$conf.int))
expect_true(!is.null(summ_90$conf.int))
# 95% CI should be wider than 90% CI
width_95 <- summ_95$conf.int[1, 2] - summ_95$conf.int[1, 1]
width_90 <- summ_90$conf.int[1, 2] - summ_90$conf.int[1, 1]
expect_true(width_95 > width_90)
})
test_that("Test 9: summary.gkwreg includes residual summary", {
# Test that summary includes residual statistics
setup <- setup_methods_data()
summ <- summary(setup$fit)
expect_true(!is.null(summ$residuals))
expect_true("Min" %in% names(summ$residuals))
expect_true("Max" %in% names(summ$residuals))
expect_true("Median" %in% names(summ$residuals))
expect_true("Mean" %in% names(summ$residuals))
})
# =============================================================================
# TESTS FOR print.summary.gkwreg (2 tests)
# =============================================================================
test_that("Test 10: print.summary.gkwreg displays formatted output", {
# Test that summary print method produces readable output
setup <- setup_methods_data()
summ <- summary(setup$fit)
expect_output(print(summ), regexp = "Generalized Kumaraswamy")
expect_output(print(summ), regexp = "Family")
expect_output(print(summ), regexp = "Coefficients")
expect_output(print(summ), regexp = "Estimate")
})
test_that("Test 11: print.summary.gkwreg respects signif.stars argument", {
# Test that significance stars can be toggled
setup <- setup_methods_data()
summ <- summary(setup$fit)
# Should work with stars
expect_no_error(print(summ, signif.stars = TRUE))
# Should work without stars
expect_no_error(print(summ, signif.stars = FALSE))
})
# =============================================================================
# TESTS FOR vcov.gkwreg (3 tests)
# =============================================================================
test_that("Test 12: vcov.gkwreg returns variance-covariance matrix", {
# Test that vcov extracts matrix correctly
setup <- setup_methods_data()
vc <- vcov(setup$fit)
expect_true(is.matrix(vc))
expect_equal(nrow(vc), length(coef(setup$fit)))
expect_equal(ncol(vc), length(coef(setup$fit)))
expect_true(isSymmetric(vc))
})
test_that("Test 13: vcov.gkwreg diagonal matches squared standard errors", {
# Test that variance matrix diagonal equals SE^2
setup <- setup_methods_data()
vc <- vcov(setup$fit)
se <- setup$fit$se
expect_equal(sqrt(diag(vc)), se, tolerance = 1e-10)
expect_equal(diag(vc), se^2, tolerance = 1e-10)
})
test_that("Test 14: vcov.gkwreg warns when Hessian not computed", {
# Test behavior when variance-covariance not available
setup <- setup_methods_data()
# Fit without Hessian
fit_no_hess <- gkwreg(y ~ x1,
data = setup$data, family = "kw",
control = gkw_control(hessian = FALSE)
)
expect_warning(vcov(fit_no_hess), regexp = "Variance-covariance matrix not found")
expect_null(suppressWarnings(vcov(fit_no_hess)))
})
# =============================================================================
# TESTS FOR nobs.gkwreg (2 tests)
# =============================================================================
test_that("Test 15: nobs.gkwreg returns correct number of observations", {
# Test that nobs returns observation count
setup <- setup_methods_data()
n <- nobs(setup$fit)
expect_type(n, "integer")
expect_equal(n, nrow(setup$data))
expect_equal(n, setup$fit$nobs)
})
test_that("Test 16: nobs.gkwreg accounts for subset and NA handling", {
# Test nobs with subset and missing data
setup <- setup_methods_data()
# Fit with subset
subset_idx <- setup$data$x1 > 0
fit_subset <- gkwreg(y ~ x1,
data = setup$data, family = "kw",
subset = subset_idx
)
n_subset <- nobs(fit_subset)
expect_equal(n_subset, sum(subset_idx))
# Fit with NA (after removing some observations)
data_na <- setup$data
data_na$y[1:5] <- NA
fit_na <- gkwreg(y ~ x1,
data = data_na, family = "kw",
na.action = na.omit
)
n_na <- nobs(fit_na)
expect_equal(n_na, nrow(setup$data) - 5)
})
# =============================================================================
# TESTS FOR confint.gkwreg (4 tests)
# =============================================================================
test_that("Test 17: confint.gkwreg returns confidence intervals", {
# Test that confint computes intervals correctly
setup <- setup_methods_data()
ci <- confint(setup$fit)
expect_true(is.matrix(ci))
expect_equal(nrow(ci), length(coef(setup$fit)))
expect_equal(ncol(ci), 2)
# Lower bound should be less than upper bound
expect_true(all(ci[, 1] < ci[, 2]))
})
test_that("Test 18: confint.gkwreg respects level argument", {
# Test that confidence level controls interval width
setup <- setup_methods_data()
ci_95 <- confint(setup$fit, level = 0.95)
ci_90 <- confint(setup$fit, level = 0.90)
ci_99 <- confint(setup$fit, level = 0.99)
# Wider confidence level = wider intervals
width_90 <- ci_90[1, 2] - ci_90[1, 1]
width_95 <- ci_95[1, 2] - ci_95[1, 1]
width_99 <- ci_99[1, 2] - ci_99[1, 1]
expect_true(width_90 < width_95)
expect_true(width_95 < width_99)
})
test_that("Test 19: confint.gkwreg allows parameter selection", {
# Test selecting specific parameters
setup <- setup_methods_data()
coef_names <- names(coef(setup$fit))
# Select by name
ci_name <- confint(setup$fit, parm = coef_names[1])
expect_equal(nrow(ci_name), 1)
expect_equal(rownames(ci_name), coef_names[1])
# Select by index
ci_idx <- confint(setup$fit, parm = 1:2)
expect_equal(nrow(ci_idx), 2)
# Select multiple by name
ci_multi <- confint(setup$fit, parm = coef_names[1:3])
expect_equal(nrow(ci_multi), 3)
})
test_that("Test 20: confint.gkwreg intervals contain point estimates", {
# Test that confidence intervals contain the coefficient estimates
setup <- setup_methods_data()
ci <- confint(setup$fit, level = 0.95)
coefs <- coef(setup$fit)
# Each coefficient should fall within its CI
for (i in seq_along(coefs)) {
expect_true(coefs[i] >= ci[i, 1])
expect_true(coefs[i] <= ci[i, 2])
}
})
# =============================================================================
# ADDITIONAL INTEGRATION TESTS
# =============================================================================
test_that("All methods work together coherently", {
# Integration test: all methods work on same object
setup <- setup_methods_data()
# All methods should work without error
expect_no_error(print(setup$fit))
expect_no_error(coef(setup$fit))
expect_no_error(summary(setup$fit))
expect_no_error(vcov(setup$fit))
expect_no_error(nobs(setup$fit))
expect_no_error(confint(setup$fit))
})
test_that("Methods work across different families", {
# Test that all methods work for different distribution families
setup <- setup_methods_data()
families <- c("kw", "beta", "ekw")
for (fam in families) {
fit <- gkwreg(y ~ x1,
data = setup$data, family = fam,
control = gkw_control(hessian = TRUE)
)
expect_no_error(coef(fit))
expect_no_error(nobs(fit))
expect_no_error(vcov(fit))
expect_no_error(summary(fit))
expect_no_error(confint(fit))
}
})
test_that("Methods handle edge cases gracefully", {
# Test methods with minimal model
setup <- setup_methods_data()
fit_minimal <- gkwreg(y ~ 1,
data = setup$data, family = "kw",
control = gkw_control(hessian = TRUE)
)
expect_equal(nobs(fit_minimal), nrow(setup$data))
expect_equal(length(coef(fit_minimal)), 2) # Two intercepts
expect_no_error(summary(fit_minimal))
expect_no_error(confint(fit_minimal))
})
test_that("summary handles models without Hessian", {
# Test summary when SE not available
setup <- setup_methods_data()
fit_no_hess <- gkwreg(y ~ x1,
data = setup$data, family = "kw",
control = gkw_control(hessian = FALSE)
)
summ <- summary(fit_no_hess)
# Should still work but with limited info
expect_s3_class(summ, "summary.gkwreg")
expect_true("Estimate" %in% colnames(summ$coefficients))
# Should not have SE, z, p-value columns
expect_false("Std. Error" %in% colnames(summ$coefficients))
})
test_that("Methods handle factor predictors correctly", {
# Test methods with categorical variables
setup <- setup_methods_data()
fit_factor <- gkwreg(y ~ x3,
data = setup$data, family = "kw",
control = gkw_control(hessian = TRUE)
)
coefs <- coef(fit_factor)
expect_true(any(grepl("x3", names(coefs))))
ci <- confint(fit_factor)
expect_equal(nrow(ci), length(coefs))
summ <- summary(fit_factor)
expect_s3_class(summ, "summary.gkwreg")
})
test_that("confint parameter selection errors for invalid input", {
# Test error handling in confint
setup <- setup_methods_data()
# Invalid parameter name
expect_error(confint(setup$fit, parm = "nonexistent"),
regexp = "parameter.*not found"
)
# Out of range index
expect_error(confint(setup$fit, parm = 999),
regexp = "out of range"
)
# Invalid level
expect_error(confint(setup$fit, level = 1.5),
regexp = "level.*between 0 and 1"
)
expect_error(confint(setup$fit, level = -0.1),
regexp = "level.*between 0 and 1"
)
})
test_that("print methods handle large coefficient names properly", {
# Test display with complex formulas
setup <- setup_methods_data()
fit_complex <- gkwreg(y ~ x1 * x2 + I(x1^2),
data = setup$data,
family = "kw"
)
expect_output(print(fit_complex), regexp = "Coefficients")
summ <- summary(fit_complex)
expect_output(print(summ), regexp = "Estimate")
})
test_that("Summary statistics are mathematically consistent", {
# Test internal consistency of summary output
setup <- setup_methods_data()
summ <- summary(setup$fit)
# nobs should match
expect_equal(summ$nobs, nobs(setup$fit))
# Coefficients should match
expect_equal(summ$coefficients[, "Estimate"], as.numeric(coef(setup$fit)))
# Standard errors should match vcov diagonal
vc <- vcov(setup$fit)
expect_equal(summ$coefficients[, "Std. Error"], as.numeric(sqrt(diag(vc))))
})
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.