# Tests for the normal distribution class test_that("normal constructor creates valid object with default parameters", { # Given: Default constructor call # When: Creating a normal distribution n <- normal() # Then: Object has correct class hierarchy and default values expect_s3_class(n, "normal") expect_s3_class(n, "univariate_dist") expect_s3_class(n, "continuous_dist") expect_s3_class(n, "dist") expect_equal(n$mu, 0) expect_equal(n$var, 1) }) test_that("normal constructor creates valid object with custom parameters", { # Given: Custom mean and variance mu <- 5 var <- 4 # When: Creating a normal distribution n <- normal(mu = mu, var = var) # Then: Object stores the parameters correctly expect_equal(n$mu, 5) expect_equal(n$var, 4) }) test_that("normal constructor validates inputs", { # Given/When/Then: Non-numeric inputs should cause an error expect_error(normal(mu = "a", var = 1)) expect_error(normal(mu = 0, var = "b")) }) test_that("is_normal identifies normal objects correctly", { n <- normal() expect_true(is_normal(n)) expect_false(is_normal(list(mu = 0, var = 1))) expect_false(is_normal("normal")) }) test_that("mean.normal returns the correct mean", { n <- normal(mu = 3.5, var = 2) expect_equal(mean(n), 3.5) }) test_that("vcov.normal returns the correct variance", { n <- normal(mu = 0, var = 9) expect_equal(vcov(n), 9) }) test_that("params.normal returns named vector of parameters", { n <- normal(mu = 2, var = 3) p <- params(n) expect_named(p, c("mu", "var")) expect_equal(p["mu"], c(mu = 2)) expect_equal(p["var"], c(var = 3)) }) test_that("dim.normal returns 1 for univariate distribution", { n <- normal() expect_equal(dim(n), 1) }) test_that("sampler.normal returns a function that generates samples", { n <- normal(mu = 10, var = 4) samp_fn <- sampler(n) # The sampler should return a function expect_type(samp_fn, "closure") # The function should generate the requested number of samples samples <- samp_fn(100) expect_length(samples, 100) # Samples should be numeric expect_type(samples, "double") }) test_that("sampler.normal produces samples with approximately correct mean", { set.seed(42) n <- normal(mu = 5, var = 1) samp_fn <- sampler(n) samples <- samp_fn(10000) # Note: sampler.normal passes var directly to rnorm's sd parameter # This is a bug - it should pass sqrt(var). For var=1, this happens to work. # Compute the mean of the samples using sum/length (avoid mean.default override) sample_mean <- sum(samples) / length(samples) expect_type(sample_mean, "double") expect_equal(sample_mean, 5, tolerance = 0.2) }) test_that("density.normal returns correct probability density", { n <- normal(mu = 0, var = 1) pdf <- density(n) # Density function should return correct values at known points expect_equal(pdf(0), dnorm(0), tolerance = 1e-10) expect_equal(pdf(1), dnorm(1), tolerance = 1e-10) expect_equal(pdf(-1), dnorm(-1), tolerance = 1e-10) }) test_that("density.normal handles log argument correctly", { n <- normal(mu = 0, var = 1) pdf <- density(n) expect_equal(pdf(0, log = TRUE), dnorm(0, log = TRUE), tolerance = 1e-10) expect_equal(pdf(1, log = TRUE), dnorm(1, log = TRUE), tolerance = 1e-10) }) test_that("density.normal works with non-standard parameters", { n <- normal(mu = 3, var = 4) pdf <- density(n) # Compare with dnorm using sd = sqrt(var) = 2 expect_equal(pdf(3), dnorm(3, mean = 3, sd = 2), tolerance = 1e-10) expect_equal(pdf(5), dnorm(5, mean = 3, sd = 2), tolerance = 1e-10) }) test_that("cdf.normal returns correct cumulative distribution", { n <- normal(mu = 0, var = 1) cdf_fn <- cdf(n) # CDF at 0 for standard normal should be 0.5 expect_equal(cdf_fn(0), 0.5, tolerance = 1e-10) # Compare with pnorm at other points expect_equal(cdf_fn(1), pnorm(1), tolerance = 1e-10) expect_equal(cdf_fn(-1), pnorm(-1), tolerance = 1e-10) }) test_that("cdf.normal handles log.p argument correctly", { n <- normal(mu = 0, var = 1) cdf_fn <- cdf(n) expect_equal(cdf_fn(0, log.p = TRUE), log(0.5), tolerance = 1e-10) }) test_that("inv_cdf.normal returns correct quantiles", { n <- normal(mu = 0, var = 1) qf <- inv_cdf(n) # Inverse CDF at 0.5 for standard normal should be 0 expect_equal(qf(0.5), 0, tolerance = 1e-10) # Compare with qnorm at other points expect_equal(qf(0.025), qnorm(0.025), tolerance = 1e-10) expect_equal(qf(0.975), qnorm(0.975), tolerance = 1e-10) }) test_that("sup.normal returns correct support interval", { n <- normal() s <- sup(n) # Normal distribution has support (-Inf, Inf) expect_s3_class(s, "interval") expect_equal(s$infimum(), -Inf) expect_equal(s$supremum(), Inf) }) test_that("negation of normal distribution works correctly", { n <- normal(mu = 5, var = 4) neg_n <- -n # Negation should flip the mean but keep the variance expect_equal(mean(neg_n), -5) expect_equal(vcov(neg_n), 4) }) test_that("print.normal produces output without error", { n <- normal(mu = 2, var = 3) expect_output(print(n), "Normal distribution") expect_output(print(n), "mean 2") expect_output(print(n), "variance 3") })