test_that("pv_self_time returns correct structure", { p <- mock_profvis() result <- pv_self_time(p) expect_s3_class(result, "data.frame") expect_named(result, c("label", "samples", "time_ms", "pct")) expect_type(result$label, "character") expect_type(result$samples, "integer") expect_type(result$time_ms, "double") expect_type(result$pct, "double") }) test_that("pv_self_time calculates self-time correctly", { p <- mock_profvis() result <- pv_self_time(p) # Self-time should only count when function is at top of stack # In mock data: inner is at top at time 1, deep at times 2,4, helper at time 3, outer at time 5 expect_true("deep" %in% result$label) expect_true("inner" %in% result$label) expect_true("helper" %in% result$label) expect_true("outer" %in% result$label) # deep appears at top of stack at times 2 and 4 = 2 samples deep_row <- result[result$label == "deep", ] expect_equal(deep_row$samples, 2L) }) test_that("pv_self_time percentages sum to 100", { p <- mock_profvis() result <- pv_self_time(p) # Percentages should sum to approximately 100 expect_equal(sum(result$pct), 100, tolerance = 0.1) }) test_that("pv_total_time returns correct structure", { p <- mock_profvis() result <- pv_total_time(p) expect_s3_class(result, "data.frame") expect_named(result, c("label", "samples", "time_ms", "pct")) }) test_that("pv_total_time calculates total time correctly", { p <- mock_profvis() result <- pv_total_time(p) # outer appears in all 5 time samples outer_row <- result[result$label == "outer", ] expect_equal(outer_row$samples, 5L) expect_equal(outer_row$pct, 100) }) test_that("pv_total_time >= pv_self_time for all functions", { p <- mock_profvis() self <- pv_self_time(p) total <- pv_total_time(p) merged <- merge(self, total, by = "label", suffixes = c("_self", "_total")) expect_true(all(merged$samples_total >= merged$samples_self)) }) test_that("time functions reject non-profvis input", { expect_error(pv_self_time(list()), "must be a profvis object") expect_error(pv_total_time(data.frame()), "must be a profvis object") }) test_that("time functions work with no source references", { p <- mock_profvis_no_source() result_self <- pv_self_time(p) result_total <- pv_total_time(p) expect_s3_class(result_self, "data.frame") expect_s3_class(result_total, "data.frame") expect_gt(nrow(result_self), 0) expect_gt(nrow(result_total), 0) })