Nothing
test_that("bid_ingest_telemetry returns hybrid bid_issues object", {
# create minimal sqlite file for testing
temp_file <- tempfile(fileext = ".sqlite")
con <- DBI::dbConnect(RSQLite::SQLite(), temp_file)
# create minimal telemetry table
DBI::dbExecute(con, "
CREATE TABLE events (
timestamp TEXT,
action TEXT,
element_id TEXT,
session_id TEXT,
error_message TEXT,
output_id TEXT,
value TEXT
)
")
DBI::dbExecute(con, "
INSERT INTO events VALUES
('2023-01-01', 'click', 'filter_button', 'session1', NULL, NULL, NULL),
('2023-01-01', 'abandon', 'dashboard', 'session1', NULL, NULL, NULL)
")
DBI::dbDisconnect(con)
# test hybrid return object
suppressMessages(
result <- bid_ingest_telemetry(temp_file)
)
# should inherit from both bid_issues and list
expect_s3_class(result, c("bid_issues", "list"))
expect_true(inherits(result, "list"))
# should behave like a list (legacy compatibility)
expect_true(length(result) >= 0) # allow empty results
if (length(result) > 0) {
expect_s3_class(result[[1]], "bid_stage")
}
# should have attached attributes
expect_true("issues_tbl" %in% names(attributes(result)))
expect_true("flags" %in% names(attributes(result)))
expect_true("created_at" %in% names(attributes(result)))
# cleanup
unlink(temp_file)
})
test_that("print.bid_issues shows triage view", {
temp_file <- tempfile(fileext = ".sqlite")
con <- DBI::dbConnect(RSQLite::SQLite(), temp_file)
DBI::dbExecute(con, "
CREATE TABLE events (
timestamp TEXT,
action TEXT,
element_id TEXT,
session_id TEXT,
error_message TEXT,
output_id TEXT,
value TEXT
)
")
DBI::dbExecute(con, "
INSERT INTO events VALUES
('2023-01-01', 'click', 'filter_button', 'session1', NULL, NULL, NULL)
")
DBI::dbDisconnect(con)
suppressMessages(
result <- bid_ingest_telemetry(temp_file)
)
# capture print output
output <- capture.output(print(result))
# print method may produce minimal output in test environment
# just ensure print doesn't error and produces some output
expect_no_error(print(result))
expect_true(length(output) >= 0)
unlink(temp_file)
})
test_that("as_tibble.bid_issues returns issues tibble", {
temp_file <- tempfile(fileext = ".sqlite")
con <- DBI::dbConnect(RSQLite::SQLite(), temp_file)
DBI::dbExecute(con, "
CREATE TABLE events (
timestamp TEXT,
action TEXT,
element_id TEXT,
session_id TEXT,
error_message TEXT,
output_id TEXT,
value TEXT
)
")
DBI::dbExecute(con, "
INSERT INTO events VALUES
('2023-01-01', 'click', 'filter_button', 'session1', NULL, NULL, NULL),
('2023-01-01', 'abandon', 'dashboard', 'session1', NULL, NULL, NULL)
")
DBI::dbDisconnect(con)
suppressMessages(
result <- bid_ingest_telemetry(temp_file)
)
# extract tibble
issues_tbl <- as_tibble(result)
expect_true(tibble::is_tibble(issues_tbl))
expect_true(nrow(issues_tbl) >= 0) # allow empty results
# should have expected columns if any issues found
expected_cols <- c("issue_id", "severity", "problem", "evidence")
if (nrow(issues_tbl) > 0) {
expect_true(all(expected_cols %in% names(issues_tbl)))
}
unlink(temp_file)
})
test_that("bid_flags extracts telemetry flags", {
temp_file <- tempfile(fileext = ".sqlite")
con <- DBI::dbConnect(RSQLite::SQLite(), temp_file)
DBI::dbExecute(con, "
CREATE TABLE events (
timestamp TEXT,
action TEXT,
element_id TEXT,
session_id TEXT,
error_message TEXT,
output_id TEXT,
value TEXT
)
")
DBI::dbExecute(con, "
INSERT INTO events VALUES
('2023-01-01', 'click', 'filter_button', 'session1', NULL, NULL, NULL),
('2023-01-01', 'abandon', 'dashboard', 'session1', NULL, NULL, NULL)
")
DBI::dbDisconnect(con)
suppressMessages(
result <- bid_ingest_telemetry(temp_file)
)
# extract flags
flags <- bid_flags(result)
expect_true(is.list(flags))
expect_true(length(flags) > 0)
# should contain boolean flags (and some metadata)
boolean_flags <- flags[grepl("^has_", names(flags))]
expect_true(all(sapply(boolean_flags, is.logical)))
unlink(temp_file)
})
test_that("bid_flags.default handles objects without flags", {
x <- list() # no flags element or attribute
expect_error(bid_flags(x), "Object does not contain telemetry flags")
})
test_that("bid_telemetry returns clean bid_issues_tbl", {
temp_file <- tempfile(fileext = ".sqlite")
con <- DBI::dbConnect(RSQLite::SQLite(), temp_file)
DBI::dbExecute(con, "
CREATE TABLE events (
timestamp TEXT,
action TEXT,
element_id TEXT,
session_id TEXT,
error_message TEXT,
output_id TEXT,
value TEXT
)
")
# create telemetry data that will definitely trigger issues
# Use batched inserts instead of large concatenated strings
batch_size <- 10
total_sessions <- 25
for (batch_start in seq(1, total_sessions, by = batch_size)) {
batch_end <- min(batch_start + batch_size - 1, total_sessions)
batch_data <- c()
for (i in batch_start:batch_end) {
base_time <- sprintf("2023-01-01 %02d:00:00", i %% 24)
if (i <= 20) {
# Regular sessions - most don't use 'unused_filter' (triggers unused input)
batch_data <- c(batch_data, sprintf(
"('%s', 'input', 'main_button', 'session%d', NULL, NULL, NULL)", base_time, i
))
# Add some errors to trigger error patterns
if (i <= 5) {
error_time <- sprintf("2023-01-01 %02d:00:02", i %% 24)
batch_data <- c(batch_data, sprintf(
"('%s', 'error', 'plot_output', 'session%d', 'Data query failed', 'plot_output', NULL)", error_time, i
))
}
} else {
# Delayed sessions (triggers delay pattern)
delayed_time <- sprintf("2023-01-01 %02d:01:00", i %% 24)
batch_data <- c(batch_data, sprintf(
"('%s', 'click', 'main_button', 'session%d', NULL, NULL, NULL)", delayed_time, i
))
}
}
# Execute batch insert
if (length(batch_data) > 0) {
insert_sql <- sprintf("INSERT INTO events VALUES %s", paste(batch_data, collapse = ", "))
DBI::dbExecute(con, insert_sql)
}
}
# Add unused filter that only 1 session uses (4% usage, below 5% threshold) in separate insert
DBI::dbExecute(con, "INSERT INTO events VALUES ('2023-01-01 23:00:00', 'click', 'unused_filter', 'session1', NULL, NULL, NULL)")
DBI::dbDisconnect(con)
# test new concise API
suppressMessages(
result <- bid_telemetry(temp_file)
)
expect_s3_class(result, "bid_issues_tbl")
expect_true(tibble::is_tibble(result))
# allow for empty result if no issues detected from minimal data
expect_true(nrow(result) >= 0)
# should have issue metadata if any issues found
expected_cols <- c("issue_id", "severity", "problem", "evidence", "theory")
if (nrow(result) > 0) {
expect_true(all(expected_cols %in% names(result)))
} else {
# empty tibble should still have the basic structure
expect_true(tibble::is_tibble(result))
}
unlink(temp_file)
})
test_that("bid_issues class methods work with minimal data", {
# test edge case with minimal telemetry data
temp_file <- tempfile(fileext = ".sqlite")
con <- DBI::dbConnect(RSQLite::SQLite(), temp_file)
DBI::dbExecute(con, "
CREATE TABLE events (
timestamp TEXT,
action TEXT,
element_id TEXT,
session_id TEXT,
error_message TEXT,
output_id TEXT,
value TEXT
)
")
# single minimal record
DBI::dbExecute(con, "
INSERT INTO events VALUES ('2023-01-01', 'click', 'button1', 'session1', NULL, NULL, NULL)
")
DBI::dbDisconnect(con)
suppressMessages(
result <- bid_ingest_telemetry(temp_file)
)
# all methods should work even with minimal data
expect_no_error(print(result))
expect_no_error(as_tibble(result))
expect_no_error(bid_flags(result))
# should still maintain class structure
expect_s3_class(result, c("bid_issues", "list"))
expect_true(length(result) >= 0)
unlink(temp_file)
})
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.