# Helper functions for testing debrief # Create a mock profvis object for testing # This allows testing without running actual profiling mock_profvis <- function( prof = NULL, interval = 10, files = NULL ) { if (is.null(prof)) { # Default simple profile data prof <- data.frame( time = c(1L, 1L, 2L, 2L, 2L, 3L, 3L, 4L, 4L, 4L, 5L), depth = c(1L, 2L, 1L, 2L, 3L, 1L, 2L, 1L, 2L, 3L, 1L), label = c( "outer", "inner", "outer", "inner", "deep", "outer", "helper", "outer", "inner", "deep", "outer" ), filename = c( "R/main.R", "R/main.R", "R/main.R", "R/main.R", "R/utils.R", "R/main.R", "R/helper.R", "R/main.R", "R/main.R", "R/utils.R", "R/main.R" ), linenum = as.double(c( 10, 15, 10, 15, 5, 10, 20, 10, 15, 5, 10 )), filenum = as.double(c(1, 1, 1, 1, 2, 1, 3, 1, 1, 2, 1)), memalloc = c(100, 150, 150, 200, 250, 250, 300, 300, 350, 400, 400), meminc = c(0, 50, 0, 50, 50, 0, 50, 0, 50, 50, 0), stringsAsFactors = FALSE ) } if (is.null(files)) { files <- list( list( filename = "R/main.R", content = paste( "# Main file", "outer <- function() {", " x <- 1", " y <- 2", " inner()", "}", "", "inner <- function() {", " result <- deep()", " result", "}", "", "", "", " z <- heavy_computation()", sep = "\n" ), normpath = "R/main.R" ), list( filename = "R/utils.R", content = paste( "# Utils", "deep <- function() {", " Sys.sleep(0.01)", " 42", " x <- rnorm(1000)", "}", sep = "\n" ), normpath = "R/utils.R" ), list( filename = "R/helper.R", content = paste( "# Helper functions", "helper <- function() {", " paste('hello', 'world')", "}", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", " do_work()", sep = "\n" ), normpath = "R/helper.R" ) ) } structure( list( x = list( message = list( prof = prof, interval = interval, files = files ) ) ), class = "profvis" ) } # Create a mock profvis with no source references mock_profvis_no_source <- function() { prof <- data.frame( time = c(1L, 1L, 2L, 2L, 3L), depth = c(1L, 2L, 1L, 2L, 1L), label = c("foo", "bar", "foo", "baz", "foo"), filename = rep(NA_character_, 5), linenum = rep(NA_real_, 5), filenum = rep(NA_real_, 5), memalloc = c(100, 150, 150, 200, 200), meminc = c(0, 50, 0, 50, 0), stringsAsFactors = FALSE ) mock_profvis(prof = prof, files = list()) } # Create a mock profvis with recursive function mock_profvis_recursive <- function() { prof <- data.frame( time = c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L), depth = c(1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 5L), label = c( "recurse", "recurse", "recurse", "recurse", "recurse", "recurse", "recurse", "recurse", "recurse", "recurse", "recurse", "recurse" ), filename = rep("R/recursive.R", 12), linenum = rep(5, 12), filenum = rep(1, 12), memalloc = seq(100, 1200, by = 100), meminc = rep(100, 12), stringsAsFactors = FALSE ) files <- list( list( filename = "R/recursive.R", content = paste( "recurse <- function(n) {", " if (n <= 0) return(1)", " recurse(n - 1)", "}", " recurse(n - 1)", sep = "\n" ), normpath = "R/recursive.R" ) ) mock_profvis(prof = prof, files = files) } # Create a mock profvis with GC and memory pressure mock_profvis_gc <- function() { prof <- data.frame( time = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L), depth = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), label = c( "work", "work", "", "work", "", "", "work", "", "work", "work" ), filename = c( rep("R/work.R", 2), NA, "R/work.R", NA, NA, "R/work.R", NA, rep("R/work.R", 2) ), linenum = as.double(c(5, 5, NA, 5, NA, NA, 5, NA, 5, 5)), filenum = as.double(c(1, 1, NA, 1, NA, NA, 1, NA, 1, 1)), memalloc = c(100, 200, 200, 300, 300, 300, 400, 400, 500, 600), meminc = c(0, 100, 0, 100, 0, 0, 100, 0, 100, 100), stringsAsFactors = FALSE ) files <- list( list( filename = "R/work.R", content = "work <- function() {\n x <- rnorm(1e6)\n y <- cumsum(x)\n z <- paste(x)\n z\n}", normpath = "R/work.R" ) ) mock_profvis(prof = prof, files = files) } # Create a mock profvis with string operations mock_profvis_strings <- function() { prof <- data.frame( time = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L), depth = c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L), label = c( "process", "paste", "process", "paste0", "process", "sprintf", "process", "gsub", "process" ), filename = rep("R/strings.R", 9), linenum = as.double(c(1, 2, 1, 3, 1, 4, 1, 5, 1)), filenum = rep(1, 9), memalloc = seq(100, 900, by = 100), meminc = rep(100, 9), stringsAsFactors = FALSE ) files <- list( list( filename = "R/strings.R", content = paste( "process <- function() {", " paste('a', 'b')", " paste0('a', 'b')", " sprintf('%s', 'a')", " gsub('a', 'b', 'aaa')", "}", sep = "\n" ), normpath = "R/strings.R" ) ) mock_profvis(prof = prof, files = files) } # Create a mock profvis with data frame operations mock_profvis_df_ops <- function() { prof <- data.frame( time = rep(1:10, each = 3), depth = rep(1:3, 10), label = rep(c("process", "loop_body", "[.data.frame"), 10), filename = rep(c("R/df.R", "R/df.R", NA), 10), linenum = as.double(rep(c(1, 5, NA), 10)), filenum = as.double(rep(c(1, 1, NA), 10)), memalloc = seq(100, 3000, by = 100), meminc = rep(c(0, 50, 50), 10), stringsAsFactors = FALSE ) files <- list( list( filename = "R/df.R", content = paste( "process <- function(df) {", " for (i in 1:nrow(df)) {", " loop_body(df, i)", " }", " df[i, ]$col", "}", sep = "\n" ), normpath = "R/df.R" ) ) mock_profvis(prof = prof, files = files) }