Nothing
# Storage base class -----------------------------------------------------------
test_that("Storage base class methods raise 'Not implemented'", {
base <- Storage$new()
expect_error(base$save("x", 1), "Not implemented")
expect_error(base$load("x"), "Not implemented")
expect_error(base$exists("x"), "Not implemented")
expect_error(base$remove("x"), "Not implemented")
expect_error(base$list(), "Not implemented")
expect_error(base$get_metadata("x"), "Not implemented")
expect_false(base$is_db())
})
# StorageLocal -----------------------------------------------------------------
test_that("StorageLocal save and load round-trips data", {
storage <- StorageLocal$new()
df <- dplyr::tibble(a = 1:3, b = letters[1:3])
storage$save("test_data", df)
loaded <- storage$load("test_data")
expect_equal(loaded, df)
})
test_that("StorageLocal preserves class and attributes", {
storage <- StorageLocal$new()
df <- dplyr::tibble(a = 1:3)
class(df) <- c("gitstats_repos", class(df))
attr(df, "since") <- "2024-01-01"
attr(df, "until") <- "2024-12-31"
storage$save("repos", df)
loaded <- storage$load("repos")
expect_s3_class(loaded, "gitstats_repos")
expect_equal(attr(loaded, "since"), "2024-01-01")
expect_equal(attr(loaded, "until"), "2024-12-31")
})
test_that("StorageLocal exists returns TRUE/FALSE correctly", {
storage <- StorageLocal$new()
expect_false(storage$exists("missing"))
storage$save("present", dplyr::tibble(x = 1))
expect_true(storage$exists("present"))
})
test_that("StorageLocal list returns saved names", {
storage <- StorageLocal$new()
expect_null(storage$list())
storage$save("alpha", dplyr::tibble(x = 1))
storage$save("beta", dplyr::tibble(y = 2))
expect_setequal(storage$list(), c("alpha", "beta"))
})
test_that("StorageLocal load returns NULL for missing data", {
storage <- StorageLocal$new()
expect_null(storage$load("nonexistent"))
})
test_that("StorageLocal overwrite replaces data", {
storage <- StorageLocal$new()
storage$save("data", dplyr::tibble(x = 1))
storage$save("data", dplyr::tibble(x = 99))
expect_equal(storage$load("data")$x, 99)
})
test_that("StorageLocal is_db returns FALSE", {
storage <- StorageLocal$new()
expect_false(storage$is_db())
})
test_that("StorageLocal remove deletes a table", {
storage <- StorageLocal$new()
storage$save("alpha", dplyr::tibble(x = 1))
storage$save("beta", dplyr::tibble(y = 2))
expect_true(storage$exists("alpha"))
storage$remove("alpha")
expect_false(storage$exists("alpha"))
expect_true(storage$exists("beta"))
expect_equal(storage$list(), "beta")
})
test_that("StorageLocal remove is silent for missing table", {
storage <- StorageLocal$new()
expect_no_error(storage$remove("nonexistent"))
})
test_that("StorageLocal get_metadata returns tibble with class and attributes", {
storage <- StorageLocal$new()
df <- dplyr::tibble(a = 1:3)
class(df) <- c("gitstats_commits", class(df))
attr(df, "since") <- "2024-01-01"
attr(df, "until") <- "2024-12-31"
storage$save("commits", df)
meta <- storage$get_metadata("commits")
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 1)
expect_equal(meta$table_name, "commits")
expect_in("gitstats_commits", meta$class[[1]])
expect_equal(meta$attributes[[1]]$since, "2024-01-01")
expect_equal(meta$attributes[[1]]$until, "2024-12-31")
})
test_that("StorageLocal get_metadata returns empty tibble for missing table", {
storage <- StorageLocal$new()
meta <- storage$get_metadata("nonexistent")
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 0)
})
test_that("StorageLocal get_metadata returns empty attributes when none set", {
storage <- StorageLocal$new()
df <- dplyr::tibble(x = 1)
storage$save("data", df)
meta <- storage$get_metadata("data")
expect_s3_class(meta, "tbl_df")
expect_equal(meta$attributes[[1]], list())
})
test_that("StorageLocal get_metadata with NULL returns all tables", {
storage <- StorageLocal$new()
df1 <- dplyr::tibble(a = 1)
class(df1) <- c("gitstats_commits", class(df1))
attr(df1, "since") <- "2024-01-01"
df2 <- dplyr::tibble(b = 2)
class(df2) <- c("gitstats_repos", class(df2))
storage$save("commits", df1)
storage$save("repos", df2)
meta <- storage$get_metadata()
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 2)
expect_in("commits", meta$table_name)
expect_in("repos", meta$table_name)
})
test_that("StorageLocal get_metadata with NULL on empty storage returns empty tibble", {
storage <- StorageLocal$new()
meta <- storage$get_metadata()
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 0)
})
# set_*_storage ----------------------------------------------------------------
test_that("default storage is StorageLocal", {
gs <- create_gitstats()
backend <- gs$.__enclos_env__$private$storage_backend
expect_s3_class(backend, "StorageLocal")
expect_false(backend$is_db())
})
test_that("set_local_storage resets to local", {
gs <- create_gitstats()
gs$set_sqlite_storage()
expect_true(gs$.__enclos_env__$private$storage_backend$is_db())
gs$set_local_storage()
expect_false(gs$.__enclos_env__$private$storage_backend$is_db())
})
test_that("set_local_storage returns self invisibly for piping", {
gs <- create_gitstats()
result <- gs$set_local_storage()
expect_identical(result, gs)
})
test_that("set_sqlite_storage returns self invisibly for piping", {
gs <- create_gitstats()
result <- gs$set_sqlite_storage()
expect_identical(result, gs)
})
test_that("print shows storage backend type for local", {
gs <- create_gitstats()
output <- capture.output(print(gs))
expect_true(any(grepl("Storage \\[local\\]", output)))
})
test_that("print shows storage backend type for SQLite", {
gs <- create_gitstats()
gs$set_sqlite_storage()
output <- capture.output(print(gs))
expect_true(any(grepl("Storage \\[SQLite\\]", output)))
})
test_that("print lists stored data on separate lines", {
gs <- create_gitstats()
gs$set_sqlite_storage()
priv <- gs$.__enclos_env__$private
repos <- dplyr::tibble(repo = c("a/b", "c/d"), stars = c(1, 2))
class(repos) <- c("gitstats_repos", class(repos))
priv$storage_backend$save("repositories", repos)
commits <- dplyr::tibble(sha = "abc123")
class(commits) <- c("gitstats_commits", class(commits))
attr(commits, "date_range") <- c("2024-01-01", "2024-06-30")
priv$storage_backend$save("commits", commits)
output <- capture.output(print(gs))
storage_lines <- output[grepl("Storage|Repositories|Commits", output)]
expect_true(any(grepl("Storage \\[SQLite\\]", storage_lines)))
expect_true(any(grepl("Repositories: 2", storage_lines)))
expect_true(any(grepl("Commits: 1", storage_lines)))
storage_label_line <- grep("Storage \\[SQLite\\]", output)
expect_false(grepl("Repositories|Commits", output[storage_label_line]))
})
# StorageSQLite ----------------------------------------------------------------
test_that("StorageSQLite save and load round-trips data", {
storage <- StorageSQLite$new()
df <- dplyr::tibble(a = 1:3, b = c("x", "y", "z"))
storage$save("test_data", df)
loaded <- storage$load("test_data")
expect_equal(loaded$a, df$a)
expect_equal(loaded$b, df$b)
})
test_that("StorageSQLite preserves class via metadata", {
storage <- StorageSQLite$new()
df <- dplyr::tibble(a = 1:3)
class(df) <- c("gitstats_commits", class(df))
storage$save("commits", df)
loaded <- storage$load("commits")
expect_s3_class(loaded, "gitstats_commits")
})
test_that("StorageSQLite preserves custom attributes via metadata", {
storage <- StorageSQLite$new()
df <- dplyr::tibble(a = 1:3)
class(df) <- c("gitstats_repos", class(df))
attr(df, "since") <- "2024-01-01"
attr(df, "until") <- "2024-12-31"
storage$save("repos", df)
loaded <- storage$load("repos")
expect_equal(attr(loaded, "since"), "2024-01-01")
expect_equal(attr(loaded, "until"), "2024-12-31")
})
test_that("StorageSQLite preserves difftime columns", {
storage <- StorageSQLite$new()
df <- dplyr::tibble(
repo = "test/repo",
last_activity = as.difftime(c(38.5, 12.3), units = "days")
)
storage$save("repos", df)
loaded <- storage$load("repos")
expect_s3_class(loaded$last_activity, "difftime")
expect_equal(attr(loaded$last_activity, "units"), "days")
expect_equal(as.numeric(loaded$last_activity), c(38.5, 12.3))
})
test_that("StorageSQLite preserves POSIXct columns", {
storage <- StorageSQLite$new()
timestamps <- as.POSIXct(c("2024-01-15 10:30:00", "2024-06-20 14:00:00"))
df <- dplyr::tibble(
repo = "test/repo",
created_at = timestamps,
last_activity_at = timestamps
)
storage$save("repos", df)
loaded <- storage$load("repos")
expect_s3_class(loaded$created_at, "POSIXct")
expect_s3_class(loaded$last_activity_at, "POSIXct")
expect_equal(
format(loaded$created_at, "%Y-%m-%d %H:%M:%S"),
format(timestamps, "%Y-%m-%d %H:%M:%S")
)
})
test_that("StorageSQLite preserves mixed difftime and POSIXct columns", {
storage <- StorageSQLite$new()
df <- dplyr::tibble(
repo = "test/repo",
created_at = as.POSIXct("2024-01-15 10:30:00"),
last_activity_at = as.POSIXct("2024-06-20 14:00:00"),
last_activity = as.difftime(38.5, units = "days")
)
class(df) <- c("gitstats_repos", class(df))
storage$save("repos", df)
loaded <- storage$load("repos")
expect_s3_class(loaded, "gitstats_repos")
expect_s3_class(loaded$created_at, "POSIXct")
expect_s3_class(loaded$last_activity_at, "POSIXct")
expect_s3_class(loaded$last_activity, "difftime")
expect_equal(as.numeric(loaded$last_activity), 38.5)
})
test_that("StorageSQLite exists returns TRUE/FALSE correctly", {
storage <- StorageSQLite$new()
expect_false(storage$exists("missing"))
storage$save("present", dplyr::tibble(x = 1))
expect_true(storage$exists("present"))
})
test_that("StorageSQLite list excludes _metadata table", {
storage <- StorageSQLite$new()
storage$save("alpha", dplyr::tibble(x = 1))
storage$save("beta", dplyr::tibble(y = 2))
tables <- storage$list()
expect_in("alpha", tables)
expect_in("beta", tables)
expect_false("_metadata" %in% tables)
})
test_that("StorageSQLite load returns NULL for missing data", {
storage <- StorageSQLite$new()
expect_null(storage$load("nonexistent"))
})
test_that("StorageSQLite overwrite replaces data", {
storage <- StorageSQLite$new()
storage$save("data", dplyr::tibble(x = 1))
storage$save("data", dplyr::tibble(x = 99))
expect_equal(storage$load("data")$x, 99)
})
test_that("StorageSQLite is_db returns TRUE", {
storage <- StorageSQLite$new()
expect_true(storage$is_db())
})
test_that("StorageSQLite remove deletes table and metadata", {
storage <- StorageSQLite$new()
df <- dplyr::tibble(a = 1:3)
class(df) <- c("gitstats_commits", class(df))
storage$save("commits", df)
storage$save("repos", dplyr::tibble(x = 1))
expect_true(storage$exists("commits"))
storage$remove("commits")
expect_false(storage$exists("commits"))
expect_true(storage$exists("repos"))
expect_equal(storage$list(), "repos")
# metadata row should also be gone
meta <- storage$get_metadata("commits")
expect_equal(nrow(meta), 0)
})
test_that("StorageSQLite remove is silent for missing table", {
storage <- StorageSQLite$new()
expect_no_error(storage$remove("nonexistent"))
})
test_that("StorageSQLite get_metadata returns tibble with class and attributes", {
storage <- StorageSQLite$new()
df <- dplyr::tibble(a = 1:3)
class(df) <- c("gitstats_repos", class(df))
attr(df, "since") <- "2024-01-01"
storage$save("repos", df)
meta <- storage$get_metadata("repos")
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 1)
expect_equal(meta$table_name, "repos")
expect_in("gitstats_repos", meta$class[[1]])
expect_equal(meta$attributes[[1]]$since, "2024-01-01")
})
test_that("StorageSQLite get_metadata returns empty tibble for missing table", {
storage <- StorageSQLite$new()
meta <- storage$get_metadata("nonexistent")
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 0)
})
test_that("StorageSQLite get_metadata with NULL returns all tables", {
storage <- StorageSQLite$new()
df1 <- dplyr::tibble(a = 1)
class(df1) <- c("gitstats_commits", class(df1))
df2 <- dplyr::tibble(b = 2)
class(df2) <- c("gitstats_repos", class(df2))
storage$save("commits", df1)
storage$save("repos", df2)
meta <- storage$get_metadata()
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 2)
expect_in("commits", meta$table_name)
expect_in("repos", meta$table_name)
})
test_that("StorageSQLite finalize disconnects connection", {
storage <- StorageSQLite$new()
conn <- storage$.__enclos_env__$private$conn
expect_true(DBI::dbIsValid(conn))
storage$.__enclos_env__$private$finalize()
expect_false(DBI::dbIsValid(conn))
})
test_that("StorageSQLite finalize handles NULL connection", {
storage <- StorageSQLite$new()
conn <- storage$.__enclos_env__$private$conn
DBI::dbDisconnect(conn)
storage$.__enclos_env__$private$conn <- NULL
expect_no_error(storage$.__enclos_env__$private$finalize())
})
test_that("StorageSQLite load works when metadata is missing", {
storage <- StorageSQLite$new()
conn <- storage$.__enclos_env__$private$conn
DBI::dbWriteTable(conn, "raw_table", data.frame(x = 1:3))
loaded <- storage$load("raw_table")
expect_equal(nrow(loaded), 3)
expect_s3_class(loaded, "tbl_df")
})
test_that("StorageSQLite works with file-based database", {
tmp <- tempfile(fileext = ".sqlite")
on.exit(unlink(tmp), add = TRUE)
storage <- StorageSQLite$new(dbname = tmp)
storage$save("data", dplyr::tibble(val = 42))
loaded <- storage$load("data")
expect_equal(loaded$val, 42)
})
test_that("set_sqlite_storage creates SQLite backend with dbname", {
tmp <- tempfile(fileext = ".sqlite")
on.exit(unlink(tmp), add = TRUE)
gs <- create_gitstats()
gs$set_sqlite_storage(dbname = tmp)
backend <- gs$.__enclos_env__$private$storage_backend
expect_s3_class(backend, "StorageSQLite")
expect_true(backend$is_db())
})
# GitStats + SQLite integration ------------------------------------------------
test_that("GitStats save_to_storage and get_from_storage work with SQLite", {
gs <- create_gitstats()
gs$set_sqlite_storage()
priv <- gs$.__enclos_env__$private
df <- dplyr::tibble(repo = "test/repo", stars = 10)
priv$storage_backend$save("repositories", df)
expect_false(priv$storage_is_empty("repositories"))
loaded <- priv$storage_backend$load("repositories")
expect_equal(loaded$repo, "test/repo")
})
test_that("GitStats get_storage returns all data from SQLite", {
gs <- create_gitstats()
gs$set_sqlite_storage()
priv <- gs$.__enclos_env__$private
priv$storage_backend$save("repos", dplyr::tibble(x = 1))
priv$storage_backend$save("commits", dplyr::tibble(y = 2))
all_data <- gs$get_storage(NULL)
expect_in("repos", names(all_data))
expect_in("commits", names(all_data))
})
test_that("GitStats get_storage returns single table from SQLite", {
gs <- create_gitstats()
gs$set_sqlite_storage()
priv <- gs$.__enclos_env__$private
priv$storage_backend$save("files", dplyr::tibble(path = "R/main.R"))
result <- gs$get_storage("files")
expect_equal(result$path, "R/main.R")
})
# GitStats remove_from_storage -------------------------------------------------
test_that("GitStats remove_from_storage removes a table", {
gs <- create_gitstats()
priv <- gs$.__enclos_env__$private
priv$storage_backend$save("commits", dplyr::tibble(sha = "abc"))
expect_true(priv$storage_backend$exists("commits"))
suppressMessages(gs$remove_from_storage("commits"))
expect_false(priv$storage_backend$exists("commits"))
})
test_that("GitStats remove_from_storage errors for missing table", {
gs <- create_gitstats()
expect_error(
gs$remove_from_storage("nonexistent"),
"nonexistent"
)
})
test_that("GitStats remove_from_storage returns self invisibly", {
gs <- create_gitstats()
priv <- gs$.__enclos_env__$private
priv$storage_backend$save("repos", dplyr::tibble(x = 1))
result <- suppressMessages(gs$remove_from_storage("repos"))
expect_identical(result, gs)
})
test_that("remove_from_storage() exported wrapper works", {
gs <- create_gitstats()
priv <- gs$.__enclos_env__$private
priv$storage_backend$save("commits", dplyr::tibble(sha = "abc"))
suppressMessages(remove_from_storage(gs, storage = "commits"))
expect_false(priv$storage_backend$exists("commits"))
})
# GitStats get_storage_metadata ------------------------------------------------
test_that("GitStats get_storage_metadata returns tibble for single table", {
gs <- create_gitstats()
priv <- gs$.__enclos_env__$private
df <- dplyr::tibble(a = 1:3)
class(df) <- c("gitstats_commits", class(df))
attr(df, "since") <- "2024-01-01"
priv$storage_backend$save("commits", df)
meta <- gs$get_storage_metadata("commits")
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 1)
expect_equal(meta$table_name, "commits")
expect_in("gitstats_commits", meta$class[[1]])
expect_equal(meta$attributes[[1]]$since, "2024-01-01")
})
test_that("GitStats get_storage_metadata errors for missing table", {
gs <- create_gitstats()
expect_error(
gs$get_storage_metadata("nonexistent"),
"nonexistent"
)
})
test_that("GitStats get_storage_metadata with NULL returns all tables", {
gs <- create_gitstats()
priv <- gs$.__enclos_env__$private
df1 <- dplyr::tibble(a = 1)
class(df1) <- c("gitstats_commits", class(df1))
df2 <- dplyr::tibble(b = 2)
class(df2) <- c("gitstats_repos", class(df2))
priv$storage_backend$save("commits", df1)
priv$storage_backend$save("repos", df2)
meta <- gs$get_storage_metadata()
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 2)
expect_in("commits", meta$table_name)
expect_in("repos", meta$table_name)
})
test_that("get_storage_metadata() exported wrapper works", {
gs <- create_gitstats()
priv <- gs$.__enclos_env__$private
df <- dplyr::tibble(x = 1)
class(df) <- c("gitstats_repos", class(df))
priv$storage_backend$save("repos", df)
meta <- get_storage_metadata(gs, storage = "repos")
expect_s3_class(meta, "tbl_df")
expect_in("gitstats_repos", meta$class[[1]])
})
test_that("get_storage_metadata() exported wrapper works with NULL", {
gs <- create_gitstats()
priv <- gs$.__enclos_env__$private
priv$storage_backend$save("commits", dplyr::tibble(sha = "abc"))
meta <- get_storage_metadata(gs)
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 1)
})
test_that("GitStats get_storage_metadata works with SQLite backend", {
gs <- create_gitstats()
gs$set_sqlite_storage()
priv <- gs$.__enclos_env__$private
df <- dplyr::tibble(a = 1:3)
class(df) <- c("gitstats_commits", class(df))
attr(df, "since") <- "2024-01-01"
priv$storage_backend$save("commits", df)
meta <- gs$get_storage_metadata("commits")
expect_s3_class(meta, "tbl_df")
expect_equal(meta$table_name, "commits")
expect_in("gitstats_commits", meta$class[[1]])
expect_equal(meta$attributes[[1]]$since, "2024-01-01")
})
test_that("GitStats get_storage_metadata with NULL works with SQLite backend", {
gs <- create_gitstats()
gs$set_sqlite_storage()
priv <- gs$.__enclos_env__$private
priv$storage_backend$save("commits", dplyr::tibble(sha = "abc"))
priv$storage_backend$save("repos", dplyr::tibble(x = 1))
meta <- gs$get_storage_metadata()
expect_s3_class(meta, "tbl_df")
expect_equal(nrow(meta), 2)
})
test_that("GitStats remove_from_storage works with SQLite backend", {
gs <- create_gitstats()
gs$set_sqlite_storage()
priv <- gs$.__enclos_env__$private
priv$storage_backend$save("commits", dplyr::tibble(sha = "abc"))
expect_true(priv$storage_backend$exists("commits"))
suppressMessages(gs$remove_from_storage("commits"))
expect_false(priv$storage_backend$exists("commits"))
})
# check_if_package_installed ---------------------------------------------------
test_that("check_if_package_installed errors for missing package", {
expect_error(
check_if_package_installed("nonexistent_pkg_12345"),
"nonexistent_pkg_12345"
)
})
test_that("check_if_package_installed passes for installed package", {
expect_no_error(check_if_package_installed("testthat"))
})
# Exported wrapper functions ----------------------------------------------------
test_that("set_local_storage() wrapper calls R6 method", {
gs <- create_gitstats()
gs$set_sqlite_storage()
result <- set_local_storage(gs)
backend <- gs$.__enclos_env__$private$storage_backend
expect_s3_class(backend, "StorageLocal")
})
test_that("set_sqlite_storage() wrapper calls R6 method", {
gs <- create_gitstats()
result <- set_sqlite_storage(gs)
backend <- gs$.__enclos_env__$private$storage_backend
expect_s3_class(backend, "StorageSQLite")
})
test_that("set_postgres_storage() R6 method executes with stubbed connection", {
gs <- create_gitstats()
mock_storage <- StorageLocal$new()
mockery::stub(
gs$set_postgres_storage,
"do.call",
mock_storage
)
gs$set_postgres_storage(
host = "localhost",
port = 5432,
dbname = "test",
user = "postgres",
password = "secret",
schema = "my_schema"
)
backend <- gs$.__enclos_env__$private$storage_backend
expect_s3_class(backend, "StorageLocal")
})
test_that("set_postgres_storage() exported wrapper calls R6 method", {
gs <- create_gitstats()
mock_storage <- StorageLocal$new()
mockery::stub(
set_postgres_storage,
"gitstats$set_postgres_storage",
mock_storage
)
set_postgres_storage(
gs,
host = "localhost",
port = 5432,
dbname = "test",
user = "postgres",
password = "secret"
)
backend <- gs$.__enclos_env__$private$storage_backend
expect_s3_class(backend, "StorageLocal")
})
test_that("print shows PostgreSQL backend type", {
gs <- create_gitstats()
mock_backend <- StorageLocal$new()
class(mock_backend) <- c("StoragePostgres", class(mock_backend))
gs$.__enclos_env__$private$storage_backend <- mock_backend
output <- capture.output(print(gs))
expect_true(any(grepl("Storage \\[PostgreSQL\\]", output)))
})
# Storage propagation to hosts -------------------------------------------------
test_that("set_sqlite_storage propagates backend to hosts", {
gs <- create_test_gitstats(hosts = 1)
suppressMessages(gs$set_sqlite_storage())
host <- gs$.__enclos_env__$private$hosts[[1]]
host_storage <- host$.__enclos_env__$private$storage_backend
expect_s3_class(host_storage, "StorageSQLite")
})
test_that("set_local_storage propagates backend to hosts", {
gs <- create_test_gitstats(hosts = 1)
suppressMessages(gs$set_sqlite_storage())
gs$set_local_storage()
host <- gs$.__enclos_env__$private$hosts[[1]]
host_storage <- host$.__enclos_env__$private$storage_backend
expect_s3_class(host_storage, "StorageLocal")
})
test_that("add_new_host propagates current storage to new host", {
gs <- create_gitstats()
suppressMessages(gs$set_sqlite_storage())
gs$.__enclos_env__$private$hosts[[1]] <- create_github_testhost(
orgs = "test_org"
)
gs$.__enclos_env__$private$propagate_storage_to_hosts()
host <- gs$.__enclos_env__$private$hosts[[1]]
host_storage <- host$.__enclos_env__$private$storage_backend
expect_s3_class(host_storage, "StorageSQLite")
})
# report_storage_contents ------------------------------------------------------
test_that("set_sqlite_storage reports empty database", {
gs <- create_gitstats()
output <- capture.output(
gs$set_sqlite_storage(),
type = "message"
)
expect_true(any(grepl("Database is empty", output)))
})
test_that("set_sqlite_storage reports existing data", {
tmp <- tempfile(fileext = ".sqlite")
on.exit(unlink(tmp), add = TRUE)
storage <- StorageSQLite$new(dbname = tmp)
df <- dplyr::tibble(repo = "test/repo", stars = 10L)
class(df) <- c("gitstats_repos", class(df))
storage$save("repositories", df)
commits <- dplyr::tibble(id = "abc123")
class(commits) <- c("gitstats_commits", class(commits))
storage$save("commits", commits)
rm(storage)
gc()
gs <- create_gitstats()
output <- capture.output(
gs$set_sqlite_storage(dbname = tmp),
type = "message"
)
expect_true(any(grepl("Database contains data", output)))
expect_true(any(grepl("repositories.*1", output)))
expect_true(any(grepl("commits.*1", output)))
})
# GitHost set_storage_backend --------------------------------------------------
test_that("GitHost set_storage_backend sets storage", {
host <- create_github_testhost(orgs = "test_org")
storage <- StorageSQLite$new()
host$set_storage_backend(storage)
host_storage <- host$.__enclos_env__$private$storage_backend
expect_s3_class(host_storage, "StorageSQLite")
})
# save_repos_to_storage --------------------------------------------------------
test_that("GitHub save_repos_to_storage saves repos to database", {
host <- create_github_testhost(orgs = "test_org")
storage <- StorageSQLite$new()
host$set_storage_backend(storage)
priv <- host$.__enclos_env__$private
mock_repos_table <- dplyr::tibble(
repo_id = "123",
repo_name = "test-repo",
default_branch = "main",
organization = "test_org"
)
mock_engine <- list(
prepare_repos_table = function(repos_from_org, org) mock_repos_table
)
priv$save_repos_to_storage(list(), "test_org", mock_engine)
loaded <- storage$load("repositories")
expect_equal(nrow(loaded), 1)
expect_equal(loaded$repo_id, "123")
expect_s3_class(loaded, "gitstats_repos")
})
test_that("GitHub save_repos_to_storage merges with existing repos", {
host <- create_github_testhost(orgs = "test_org")
storage <- StorageSQLite$new()
host$set_storage_backend(storage)
priv <- host$.__enclos_env__$private
existing <- dplyr::tibble(
repo_id = "100",
repo_name = "old-repo",
default_branch = "main",
organization = "old_org"
)
class(existing) <- c("gitstats_repos", class(existing))
storage$save("repositories", existing)
new_repos <- dplyr::tibble(
repo_id = "200",
repo_name = "new-repo",
default_branch = "main",
organization = "test_org"
)
mock_engine <- list(
prepare_repos_table = function(repos_from_org, org) new_repos
)
priv$save_repos_to_storage(list(), "test_org", mock_engine)
loaded <- storage$load("repositories")
expect_equal(nrow(loaded), 2)
expect_in("100", loaded$repo_id)
expect_in("200", loaded$repo_id)
})
test_that("GitHub save_repos_to_storage deduplicates by repo_id", {
host <- create_github_testhost(orgs = "test_org")
storage <- StorageSQLite$new()
host$set_storage_backend(storage)
priv <- host$.__enclos_env__$private
existing <- dplyr::tibble(
repo_id = "123",
repo_name = "test-repo",
default_branch = "main",
organization = "test_org"
)
class(existing) <- c("gitstats_repos", class(existing))
storage$save("repositories", existing)
duplicate_repos <- dplyr::tibble(
repo_id = "123",
repo_name = "test-repo-updated",
default_branch = "develop",
organization = "test_org"
)
mock_engine <- list(
prepare_repos_table = function(repos_from_org, org) duplicate_repos
)
priv$save_repos_to_storage(list(), "test_org", mock_engine)
loaded <- storage$load("repositories")
expect_equal(nrow(loaded), 1)
})
test_that("GitHub save_repos_to_storage skips when no db storage", {
host <- create_github_testhost(orgs = "test_org")
priv <- host$.__enclos_env__$private
# storage_backend is NULL by default
expect_no_error(
priv$save_repos_to_storage(list(), "test_org", list())
)
})
test_that("GitHub save_repos_to_storage skips when storage is local", {
host <- create_github_testhost(orgs = "test_org")
storage <- StorageLocal$new()
host$set_storage_backend(storage)
priv <- host$.__enclos_env__$private
mock_engine <- list(
prepare_repos_table = function(repos_from_org, org) {
dplyr::tibble(repo_id = "1", repo_name = "r")
}
)
priv$save_repos_to_storage(list(), "test_org", mock_engine)
expect_null(storage$load("repositories"))
})
test_that("GitLab save_repos_to_storage saves repos to database", {
host <- create_gitlab_testhost(orgs = "test_group")
storage <- StorageSQLite$new()
host$set_storage_backend(storage)
priv <- host$.__enclos_env__$private
mock_repos_table <- dplyr::tibble(
repo_id = "456",
repo_name = "gl-repo",
default_branch = "main",
organization = "test_group"
)
mock_engine <- list(
prepare_repos_table = function(repos_from_org, org) mock_repos_table
)
priv$save_repos_to_storage(list(), "test_group", mock_engine)
loaded <- storage$load("repositories")
expect_equal(nrow(loaded), 1)
expect_equal(loaded$repo_id, "456")
expect_s3_class(loaded, "gitstats_repos")
})
# add_new_host propagates storage ----------------------------------------------
test_that("add_new_host propagates storage backend to host", {
gs <- create_gitstats()
suppressMessages(gs$set_sqlite_storage())
priv <- gs$.__enclos_env__$private
new_host <- create_github_testhost(orgs = "test_org")
priv$add_new_host(new_host)
host_storage <- priv$hosts[[1]]$.__enclos_env__$private$storage_backend
expect_s3_class(host_storage, "StorageSQLite")
})
# Storage drop_storage ---------------------------------------------------------
test_that("Storage base class drop_storage raises 'Not implemented'", {
base <- Storage$new()
expect_error(base$drop_storage(), "Not implemented")
})
test_that("StorageLocal drop_storage clears all data", {
storage <- StorageLocal$new()
storage$save("alpha", dplyr::tibble(x = 1))
storage$save("beta", dplyr::tibble(y = 2))
expect_length(storage$list(), 2)
storage$drop_storage()
expect_null(storage$list())
})
test_that("StorageSQLite drop_storage removes file-based database", {
tmp <- tempfile(fileext = ".sqlite")
storage <- StorageSQLite$new(dbname = tmp)
storage$save("commits", dplyr::tibble(sha = "abc"))
expect_true(file.exists(tmp))
storage$drop_storage()
expect_false(file.exists(tmp))
})
test_that("StorageSQLite drop_storage works for in-memory database", {
storage <- StorageSQLite$new()
storage$save("commits", dplyr::tibble(sha = "abc"))
expect_no_error(storage$drop_storage())
})
test_that("StorageSQLite stores dbname in private field", {
tmp <- tempfile(fileext = ".sqlite")
on.exit(unlink(tmp), add = TRUE)
storage <- StorageSQLite$new(dbname = tmp)
expect_equal(storage$.__enclos_env__$private$dbname, tmp)
})
# GitStats remove_sqlite_storage -----------------------------------------------
test_that("remove_sqlite_storage removes file-based SQLite and reverts to local", {
tmp <- tempfile(fileext = ".sqlite")
gs <- create_gitstats()
gs$set_sqlite_storage(dbname = tmp)
priv <- gs$.__enclos_env__$private
priv$storage_backend$save("commits", dplyr::tibble(sha = "abc"))
expect_true(file.exists(tmp))
suppressMessages(gs$remove_sqlite_storage())
expect_false(file.exists(tmp))
expect_s3_class(priv$storage_backend, "StorageLocal")
})
test_that("remove_sqlite_storage removes in-memory SQLite and reverts to local", {
gs <- create_gitstats()
gs$set_sqlite_storage()
priv <- gs$.__enclos_env__$private
expect_s3_class(priv$storage_backend, "StorageSQLite")
suppressMessages(gs$remove_sqlite_storage())
expect_s3_class(priv$storage_backend, "StorageLocal")
})
test_that("remove_sqlite_storage errors when no SQLite backend is set", {
gs <- create_gitstats()
expect_error(
gs$remove_sqlite_storage(),
"No SQLite storage"
)
})
test_that("remove_sqlite_storage returns self invisibly", {
gs <- create_gitstats()
gs$set_sqlite_storage()
result <- suppressMessages(gs$remove_sqlite_storage())
expect_identical(result, gs)
})
test_that("remove_sqlite_storage propagates local storage to hosts", {
gs <- create_test_gitstats(hosts = 1)
suppressMessages(gs$set_sqlite_storage())
host <- gs$.__enclos_env__$private$hosts[[1]]
expect_s3_class(host$.__enclos_env__$private$storage_backend, "StorageSQLite")
suppressMessages(gs$remove_sqlite_storage())
expect_s3_class(host$.__enclos_env__$private$storage_backend, "StorageLocal")
})
test_that("remove_sqlite_storage() exported wrapper works", {
gs <- create_gitstats()
gs$set_sqlite_storage()
suppressMessages(remove_sqlite_storage(gs))
backend <- gs$.__enclos_env__$private$storage_backend
expect_s3_class(backend, "StorageLocal")
})
test_that("remove_sqlite_storage prints file removal message", {
tmp <- tempfile(fileext = ".sqlite")
gs <- create_gitstats()
gs$set_sqlite_storage(dbname = tmp)
output <- capture.output(
gs$remove_sqlite_storage(),
type = "message"
)
expect_true(any(grepl("removed", output, ignore.case = TRUE)))
expect_true(any(grepl("local", output)))
})
test_that("remove_sqlite_storage prints in-memory removal message", {
gs <- create_gitstats()
gs$set_sqlite_storage()
output <- capture.output(
gs$remove_sqlite_storage(),
type = "message"
)
expect_true(any(grepl("In-memory", output)))
expect_true(any(grepl("local", output)))
})
# GitStats remove_postgres_storage ---------------------------------------------
test_that("remove_postgres_storage errors when no PostgreSQL backend is set", {
gs <- create_gitstats()
expect_error(
gs$remove_postgres_storage(),
"No PostgreSQL storage"
)
})
test_that("remove_postgres_storage errors when SQLite is set instead", {
gs <- create_gitstats()
gs$set_sqlite_storage()
expect_error(
gs$remove_postgres_storage(),
"No PostgreSQL storage"
)
})
test_that("remove_postgres_storage R6 method works with stubbed backend", {
gs <- create_gitstats()
mock_backend <- StorageLocal$new()
class(mock_backend) <- c("StoragePostgres", class(mock_backend))
gs$.__enclos_env__$private$storage_backend <- mock_backend
suppressMessages(gs$remove_postgres_storage())
backend <- gs$.__enclos_env__$private$storage_backend
expect_s3_class(backend, "StorageLocal")
expect_false(inherits(backend, "StoragePostgres"))
})
test_that("remove_postgres_storage() exported wrapper works with stubbed backend", {
gs <- create_gitstats()
mock_backend <- StorageLocal$new()
class(mock_backend) <- c("StoragePostgres", class(mock_backend))
gs$.__enclos_env__$private$storage_backend <- mock_backend
suppressMessages(remove_postgres_storage(gs))
backend <- gs$.__enclos_env__$private$storage_backend
expect_s3_class(backend, "StorageLocal")
})
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.