Nothing
library(testthat)
library(cgmguru)
library(iglu)
# Use example CGM data from iglu
data(example_data_5_subject)
empty_cgm <- data.frame(
id = character(0),
time = as.POSIXct(character(0), tz = "UTC"),
gl = numeric(0),
stringsAsFactors = FALSE
)
test_that("detect_hypoglycemic_events wrapper returns expected structure and validates", {
res <- detect_hypoglycemic_events(example_data_5_subject, start_gl = 70, dur_length = 15, end_length = 15)
expect_true(is.list(res))
expect_true(all(c("events_detailed", "events_total") %in% names(res)))
expect_true(is.data.frame(res$events_detailed))
expect_true(is.data.frame(res$events_total))
# Empty input should not error and should return empty data.frames
res_empty <- detect_hypoglycemic_events(empty_cgm)
expect_true(is.list(res_empty))
expect_true(nrow(res_empty$events_detailed) == 0)
expect_true(nrow(res_empty$events_total) == 0)
# Parameter validation - these should work now with overrides active
expect_error(detect_hypoglycemic_events(example_data_5_subject, dur_length = -1),
"dur_length must be between 0 and Inf")
expect_error(detect_hypoglycemic_events(example_data_5_subject, end_length = -1),
"end_length must be between 0 and Inf")
expect_error(detect_hypoglycemic_events(example_data_5_subject, start_gl = -1),
"start_gl must be between 0 and Inf")
})
test_that("detect_all_events wrapper returns a data.frame and validates reading_minutes", {
res <- detect_all_events(example_data_5_subject)
expect_true(is.data.frame(res))
# Single numeric reading_minutes is accepted
res5 <- detect_all_events(example_data_5_subject, reading_minutes = 5)
expect_true(is.data.frame(res5))
# reading_minutes vector of wrong length should error
expect_error(detect_all_events(example_data_5_subject, reading_minutes = c(5, 5)),
"reading_minutes vector length must match data length or be a single value")
# Empty input returns empty data.frame
res_empty <- detect_all_events(empty_cgm)
expect_true(is.data.frame(res_empty))
expect_true(nrow(res_empty) == 0)
})
test_that("find_local_maxima wrapper returns expected components", {
res <- find_local_maxima(example_data_5_subject)
expect_true(is.list(res))
expect_true(all(c("local_maxima_vector", "merged_results") %in% names(res)))
expect_true(is.data.frame(res$local_maxima_vector))
expect_true(is.data.frame(res$merged_results))
})
test_that("grid wrapper returns expected components and validates", {
res <- grid(example_data_5_subject, gap = 15, threshold = 130)
expect_true(is.list(res))
expect_true(all(c("grid_vector", "episode_counts", "episode_start") %in% names(res)))
expect_true(is.data.frame(res$grid_vector))
expect_error(grid(example_data_5_subject, gap = -1),
"gap must be between 0 and Inf")
expect_error(grid(example_data_5_subject, threshold = -1),
"threshold must be between 0 and Inf")
})
test_that("maxima_grid wrapper returns list with expected components and validates", {
res <- maxima_grid(example_data_5_subject, threshold = 130, gap = 60, hours = 2)
expect_true(is.list(res))
expect_true(all(c("results", "episode_counts") %in% names(res)))
expect_true(is.data.frame(res$results))
expect_error(maxima_grid(example_data_5_subject, threshold = -1),
"threshold must be between 0 and Inf")
expect_error(maxima_grid(example_data_5_subject, gap = -1),
"gap must be between 0 and Inf")
expect_error(maxima_grid(example_data_5_subject, hours = -1),
"hours must be between 0 and Inf")
})
test_that("excursion wrapper returns list and validates", {
res <- excursion(example_data_5_subject, gap = 15)
expect_true(is.list(res))
expect_true(all(c("excursion_vector", "episode_counts", "episode_start") %in% names(res)))
expect_error(excursion(example_data_5_subject, gap = -1),
"gap must be between 0 and Inf")
})
test_that("start_finder wrapper returns expected type", {
res <- start_finder(example_data_5_subject)
expect_true(is.list(res) || is.data.frame(res))
})
test_that("find_max/min before/after hours wrappers validate inputs and return data", {
# Use small subset to form a valid start point df
start_points <- head(example_data_5_subject, 10)
r1 <- find_max_after_hours(example_data_5_subject, start_points, hours = 1)
expect_true(is.list(r1) || is.data.frame(r1))
expect_error(find_max_after_hours(example_data_5_subject, start_points, hours = -1),
"hours must be between 0 and Inf")
r2 <- find_max_before_hours(example_data_5_subject, start_points, hours = 1)
expect_true(is.list(r2) || is.data.frame(r2))
expect_error(find_max_before_hours(example_data_5_subject, start_points, hours = -1),
"hours must be between 0 and Inf")
r3 <- find_min_after_hours(example_data_5_subject, start_points, hours = 1)
expect_true(is.list(r3) || is.data.frame(r3))
expect_error(find_min_after_hours(example_data_5_subject, start_points, hours = -1),
"hours must be between 0 and Inf")
r4 <- find_min_before_hours(example_data_5_subject, start_points, hours = 1)
expect_true(is.list(r4) || is.data.frame(r4))
expect_error(find_min_before_hours(example_data_5_subject, start_points, hours = -1),
"hours must be between 0 and Inf")
})
test_that("mod_grid works with grid results as grid_point_df", {
gr <- grid(example_data_5_subject, gap = 15, threshold = 130)
mg <- mod_grid(example_data_5_subject, gr$grid_vector, hours = 2, gap = 15)
expect_true(is.list(mg))
expect_true(is.data.frame(mg$mod_grid_vector))
})
test_that("end-to-end pipeline produces compatible frames for transform_df and detect_between_maxima", {
gap <- 15
threshold <- 130
hours <- 2
# 1) GRID points
grid_result <- grid(example_data_5_subject, gap = gap, threshold = threshold)
expect_true(is.list(grid_result))
expect_true(is.data.frame(grid_result$episode_start))
# 2) Modified GRID points before 2 hours minimum
mod_grid_result <- mod_grid(example_data_5_subject,
start_finder(grid_result$grid_vector),
hours = hours,
gap = gap)
expect_true(is.list(mod_grid_result) || is.data.frame(mod_grid_result))
# 3) Max point 2 hours after mod_grid point
max_after <- find_max_after_hours(example_data_5_subject,
start_finder(mod_grid_result$mod_grid_vector),
hours = hours)
expect_true(is.list(max_after) || is.data.frame(max_after))
# 4) Local maxima
local_maxima <- find_local_maxima(example_data_5_subject)
expect_true(is.list(local_maxima))
# 5) Among local maxima, find maximum point after two hours
final_maxima <- find_new_maxima(example_data_5_subject,
max_after$max_indices,
local_maxima$local_maxima_vector)
expect_true(is.data.frame(final_maxima))
# 6) Map GRID points to maximum points (within 4 hours)
transformed <- transform_df(grid_result$episode_start, final_maxima)
expect_true(is.data.frame(transformed))
# 7) Redistribute overlapping maxima between GRID points
between <- detect_between_maxima(example_data_5_subject, transformed)
expect_true(is.list(between) || is.data.frame(between))
})
test_that("detect_hyperglycemic_events works correctly", {
# Test Level 1 Hyperglycemia Event (≥15 consecutive min of >180 mg/dL)
result_lv1 <- detect_hyperglycemic_events(
example_data_5_subject,
start_gl = 180,
dur_length = 15,
end_length = 15,
end_gl = 180
)
# Test that the function returns the expected structure
expect_true(is.list(result_lv1))
expect_true("events_detailed" %in% names(result_lv1))
expect_true("events_total" %in% names(result_lv1))
# Test Level 2 Hyperglycemia Event (≥15 consecutive min of >250 mg/dL)
result_lv2 <- detect_hyperglycemic_events(
example_data_5_subject,
start_gl = 250,
dur_length = 15,
end_length = 15,
end_gl = 250
)
expect_true(is.list(result_lv2))
expect_true(is.data.frame(result_lv2$events_detailed))
expect_true(is.data.frame(result_lv2$events_total))
# Test Extended Hyperglycemia Event (default parameters)
result_extended <- detect_hyperglycemic_events(example_data_5_subject)
expect_true(is.list(result_extended))
expect_true(is.data.frame(result_extended$events_detailed))
expect_true(is.data.frame(result_extended$events_total))
})
test_that("detect_hyperglycemic_events handles edge cases", {
# Test with empty data - create proper data types
empty_data <- data.frame(
id = character(0),
time = as.POSIXct(character(0), tz = "UTC"),
gl = numeric(0),
stringsAsFactors = FALSE
)
result_empty <- detect_hyperglycemic_events(empty_data)
expect_true(is.list(result_empty))
expect_equal(nrow(result_empty$events_detailed), 0)
expect_true(is.data.frame(result_empty$events_total))
expect_equal(nrow(result_empty$events_total), 0)
})
test_that("detect_hyperglycemic_events handles empty data", {
# Test with empty data - should return empty results without crashing
empty_data <- data.frame(
id = character(0),
time = character(0),
gl = numeric(0)
)
# This should NOT crash - it should return empty results
result <- detect_hyperglycemic_events(empty_data)
expect_true(is.list(result))
expect_equal(nrow(result$events_detailed), 0)
expect_equal(nrow(result$events_total), 0)
})
test_that("detect_hyperglycemic_events validates parameters", {
# Test with invalid parameters
expect_error(detect_hyperglycemic_events(example_data_5_subject, dur_length = -1), "dur_length must be between 0 and Inf")
expect_error(detect_hyperglycemic_events(example_data_5_subject, start_gl = -1), "start_gl must be between 0 and Inf")
})
# Note: Parameter validation tests removed as the function doesn't validate input parameters
test_that("detect_hyperglycemic_events returns expected column names", {
result <- detect_hyperglycemic_events(example_data_5_subject, start_gl = 180, dur_length = 15, end_length = 15, end_gl = 180)
# Check events_detailed columns
expected_cols <- c("id", "start_time", "start_glucose", "end_time", "end_glucose",
"start_indices", "end_indices")
expect_true(all(expected_cols %in% names(result$events_detailed)))
# Check events_total columns
expected_total_cols <- c("id", "total_events", "avg_ep_per_day")
expect_true(all(expected_total_cols %in% names(result$events_total)))
})
test_that("detect_hyperglycemic_events with different parameters produces different results", {
# Level 1 vs Level 2 should produce different results
result_lv1 <- detect_hyperglycemic_events(example_data_5_subject, start_gl = 180, dur_length = 15, end_length = 15, end_gl = 180)
result_lv2 <- detect_hyperglycemic_events(example_data_5_subject, start_gl = 250, dur_length = 15, end_length = 15, end_gl = 250)
# They should have different number of events (Level 1 should detect more events than Level 2)
total_lv1 <- sum(result_lv1$events_total$total_events)
total_lv2 <- sum(result_lv2$events_total$total_events)
expect_true(total_lv1 >= total_lv2, info = "Level 1 hyperglycemia should detect more or equal events than Level 2")
})
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.