test_that("xrd_deconvolve recovers known peak centers and a high crystallinity index", { set.seed(1) two_theta <- seq(10, 40, by = 0.1) intensity <- 300 * exp(-((two_theta - 22)^2) / (2 * 0.8^2)) + 150 * exp(-((two_theta - 29)^2) / (2 * 0.6^2)) + stats::rnorm(length(two_theta), 0, 3) intensity <- pmax(0, intensity) res <- xrd_deconvolve(two_theta, intensity, peak_centers = c(22, 29)) expect_equal(res$peaks$center, c(22, 29), tolerance = 0.2) expect_true(res$crystallinity_index > 0.9) expect_true(res$R2 > 0.95) }) test_that("xrd_deconvolve errors with no peak centers", { expect_error(xrd_deconvolve(1:10, 1:10, peak_centers = numeric(0)), "at least one") }) test_that("bet_surface_area returns a positive, plausible surface area", { P_P0 <- c(0.05, 0.10, 0.15, 0.20, 0.25, 0.30) Q <- c(12.1, 15.8, 18.9, 21.6, 24.1, 26.8) res <- bet_surface_area(P_P0, Q) expect_true(res$SBET_m2g > 0) expect_true(res$Qm_cm3g > 0) expect_true(res$R2 > 0.95) }) test_that("bet_surface_area errors with too few points", { expect_error(bet_surface_area(c(0.1, 0.2), c(10, 15)), "at least 3") }) test_that("pct_mass_change computes correct percentage", { expect_equal(pct_mass_change(5.000, 4.750), 5) }) test_that("proximate_analysis computes fixed carbon by difference and warns if over 100", { out <- proximate_analysis(3.2, 28.5, 12.1) expect_equal(out$fixed_carbon_pct, 56.2) expect_warning(proximate_analysis(50, 40, 20), "exceeds 100") }) test_that("ultimate_ratios computes plausible atomic ratios", { out <- ultimate_ratios(65.2, 2.8, 18.4, N_pct = 1.1) expect_true(out$HC_ratio > 0 && out$HC_ratio < 2) expect_true(out$OC_ratio > 0 && out$OC_ratio < 1) expect_true("NC_ratio" %in% names(out)) }) test_that("ultimate_ratios omits NC_ratio when N_pct not supplied", { out <- ultimate_ratios(65.2, 2.8, 18.4) expect_false("NC_ratio" %in% names(out)) })