# Test fixture constructors for data source tests # Simple data frame with id, name, and value columns new_test_df <- function(rows = 5) { data.frame( id = seq_len(rows), name = c("A", "B", "C", "D", "E")[seq_len(rows)], value = c(10, 20, 30, 40, 50)[seq_len(rows)], stringsAsFactors = FALSE ) } # Data frame with multiple numeric columns for testing min/max ranges new_metrics_df <- function() { data.frame( id = 1:5, score = c(10.5, 20.3, 15.7, 30.1, 25.9), count = c(100, 200, 150, 50, 75), stringsAsFactors = FALSE ) } # Data frame with mixed types including boolean new_mixed_types_df <- function() { data.frame( id = 1:5, name = c("A", "B", "C", "D", "E"), active = c(TRUE, FALSE, TRUE, TRUE, FALSE), stringsAsFactors = FALSE ) } # Data frame for testing user data new_users_df <- function() { data.frame( id = 1:5, name = c("Alice", "Bob", "Charlie", "Diana", "Eve"), age = c(25, 30, 35, 28, 32), stringsAsFactors = FALSE ) } # Data frame with all data types for type testing new_types_df <- function() { data.frame( id = 1:3, text_col = c("text1", "text2", "text3"), num_col = c(1.1, 2.2, 3.3), int_col = c(10L, 20L, 30L), bool_col = c(TRUE, FALSE, TRUE), stringsAsFactors = FALSE ) } # Create a temporary SQLite connection with a test table local_sqlite_connection <- function( data = new_test_df(), table_name = "test_table", env = parent.frame() ) { if (testthat::is_testing()) { skip_if_not_installed("RSQLite") } temp_db <- withr::local_tempfile(fileext = ".db", .local_envir = env) conn <- DBI::dbConnect(RSQLite::SQLite(), temp_db) withr::defer(DBI::dbDisconnect(conn), envir = env) DBI::dbWriteTable(conn, table_name, data, overwrite = TRUE) list(conn = conn, path = temp_db) } # Skip test if no DataFrameSource engine is available skip_if_no_dataframe_engine <- function() { if (!rlang::is_installed("duckdb") && !rlang::is_installed("RSQLite")) { skip("Neither duckdb nor RSQLite is installed") } } # Create a DataFrameSource with automatic cleanup local_data_frame_source <- function( data, table_name = "test_table", engine = "duckdb", env = parent.frame() ) { df_source <- DataFrameSource$new(data, table_name, engine = engine) withr::defer(df_source$cleanup(), envir = env) df_source } local_querychat <- function( data_source = new_test_df(), table_name = "test_table", ..., env = parent.frame() ) { qc <- QueryChat$new(data_source, table_name, ...) withr::defer(qc$cleanup(), envir = env) qc } # Create a TblSqlSource with DuckDB and automatic cleanup local_tbl_sql_source <- function( data = new_test_df(), table_name = "test_table", tbl_transform = identity, env = parent.frame() ) { skip_if_not_installed("duckdb") skip_if_not_installed("dbplyr") skip_if_not_installed("dplyr") conn <- DBI::dbConnect(duckdb::duckdb(), dbdir = ":memory:") withr::defer(DBI::dbDisconnect(conn, shutdown = TRUE), envir = env) DBI::dbWriteTable(conn, table_name, data, overwrite = TRUE) tbl <- dplyr::tbl(conn, table_name) tbl <- tbl_transform(tbl) TblSqlSource$new(tbl, table_name) } # Create a DuckDB connection with multiple tables for JOIN tests local_duckdb_multi_table <- function( env = parent.frame() ) { skip_if_not_installed("duckdb") conn <- DBI::dbConnect(duckdb::duckdb(), dbdir = ":memory:") withr::defer(DBI::dbDisconnect(conn, shutdown = TRUE), envir = env) # Table A with id and name DBI::dbWriteTable( conn, "table_a", data.frame( id = 1:3, name = c("Alice", "Bob", "Carol"), stringsAsFactors = FALSE ) ) # Table B with id and value DBI::dbWriteTable( conn, "table_b", data.frame( id = 1:3, value = c(100, 200, 300), stringsAsFactors = FALSE ) ) conn } mock_ellmer_chat_client <- function( public = list(), private = list(), env = parent.frame() ) { MockChat <- R6::R6Class( "MockChat", inherit = asNamespace("ellmer")[["Chat"]], public = public, private = private ) MockChat$new(ellmer::Provider("test", "test", "test")) }