Nothing
# Tests for input-parse.R and related input parsing functions
# Coverage target: 40% improvement for input-parse.R
# =============================================================================
# parse_input() tests - Main dispatch function
# =============================================================================
skip_on_cran()
test_that("parse_input dispatches to parse_matrix for matrix input", {
m <- matrix(c(0, 1, 1, 1, 0, 1, 1, 1, 0), nrow = 3)
result <- parse_input(m)
expect_type(result, "list")
expect_true("nodes" %in% names(result))
expect_true("edges" %in% names(result))
expect_true("directed" %in% names(result))
})
test_that("parse_input dispatches to parse_edgelist for data.frame input", {
df <- data.frame(from = c("A", "B"), to = c("B", "C"), weight = c(0.5, 0.8))
result <- parse_input(df)
expect_type(result, "list")
expect_true("nodes" %in% names(result))
expect_true("edges" %in% names(result))
})
test_that("parse_input returns already parsed format unchanged", {
already_parsed <- list(
nodes = data.frame(id = 1:3, label = c("A", "B", "C"), stringsAsFactors = FALSE),
edges = data.frame(from = c(1, 2), to = c(2, 3), weight = c(0.5, 0.8), stringsAsFactors = FALSE),
directed = FALSE
)
result <- parse_input(already_parsed)
expect_identical(result, already_parsed)
})
test_that("parse_input errors on unsupported input type", {
expect_error(
parse_input("not a valid input"),
"Unsupported input type"
)
expect_error(
parse_input(123),
"Unsupported input type"
)
expect_error(
parse_input(list(foo = 1, bar = 2)),
"Unsupported input type"
)
})
test_that("parse_input passes directed parameter correctly", {
# Symmetric matrix but force directed = TRUE
m <- matrix(c(0, 1, 1, 1, 0, 1, 1, 1, 0), nrow = 3)
result <- parse_input(m, directed = TRUE)
expect_true(result$directed)
# Same matrix with directed = FALSE
result2 <- parse_input(m, directed = FALSE)
expect_false(result2$directed)
})
# =============================================================================
# is_symmetric_matrix() tests
# =============================================================================
test_that("is_symmetric_matrix returns TRUE for symmetric matrix", {
m <- matrix(c(0, 1, 2, 1, 0, 3, 2, 3, 0), nrow = 3)
expect_true(is_symmetric_matrix(m))
})
test_that("is_symmetric_matrix returns FALSE for asymmetric matrix", {
m <- matrix(c(0, 1, 0, 0, 0, 1, 1, 0, 0), nrow = 3)
expect_false(is_symmetric_matrix(m))
})
test_that("is_symmetric_matrix returns FALSE for non-square matrix", {
m <- matrix(1:6, nrow = 2, ncol = 3)
expect_false(is_symmetric_matrix(m))
})
test_that("is_symmetric_matrix returns FALSE for non-matrix input", {
expect_false(is_symmetric_matrix(c(1, 2, 3)))
expect_false(is_symmetric_matrix(data.frame(a = 1:3)))
expect_false(is_symmetric_matrix(NULL))
})
test_that("is_symmetric_matrix handles numeric tolerance", {
m <- matrix(c(0, 1, 1 + 1e-10, 1, 0, 1, 1, 1, 0), nrow = 3)
# With default tolerance, should be symmetric
expect_true(is_symmetric_matrix(m))
# With very strict tolerance, should be asymmetric
expect_false(is_symmetric_matrix(m, tol = 1e-15))
})
# =============================================================================
# create_nodes_df() tests
# =============================================================================
test_that("create_nodes_df creates correct structure", {
result <- create_nodes_df(5)
expect_s3_class(result, "data.frame")
expect_equal(nrow(result), 5)
expect_true(all(c("id", "label", "name", "x", "y") %in% names(result)))
expect_equal(result$id, 1:5)
expect_equal(result$label, as.character(1:5))
})
test_that("create_nodes_df uses provided labels", {
result <- create_nodes_df(3, labels = c("A", "B", "C"))
expect_equal(result$label, c("A", "B", "C"))
expect_equal(result$name, c("A", "B", "C"))
})
test_that("create_nodes_df uses provided names", {
result <- create_nodes_df(3, labels = c("A", "B", "C"), names = c("Alpha", "Beta", "Gamma"))
expect_equal(result$label, c("A", "B", "C"))
expect_equal(result$name, c("Alpha", "Beta", "Gamma"))
})
test_that("create_nodes_df initializes x and y as NA", {
result <- create_nodes_df(3)
expect_true(all(is.na(result$x)))
expect_true(all(is.na(result$y)))
})
test_that("create_nodes_df handles single node", {
result <- create_nodes_df(1)
expect_equal(nrow(result), 1)
expect_equal(result$id, 1)
expect_equal(result$label, "1")
})
# =============================================================================
# create_edges_df() tests
# =============================================================================
test_that("create_edges_df creates correct structure", {
result <- create_edges_df(from = c(1, 2, 3), to = c(2, 3, 1))
expect_s3_class(result, "data.frame")
expect_equal(nrow(result), 3)
expect_true(all(c("from", "to", "weight") %in% names(result)))
})
test_that("create_edges_df uses default weight of 1", {
result <- create_edges_df(from = c(1, 2), to = c(2, 3))
expect_equal(result$weight, c(1, 1))
})
test_that("create_edges_df uses provided weights", {
result <- create_edges_df(from = c(1, 2), to = c(2, 3), weight = c(0.5, 1.5))
expect_equal(result$weight, c(0.5, 1.5))
})
test_that("create_edges_df handles empty edges", {
result <- create_edges_df(from = integer(0), to = integer(0))
expect_equal(nrow(result), 0)
expect_true(all(c("from", "to", "weight") %in% names(result)))
})
# =============================================================================
# detect_duplicate_edges() tests
# =============================================================================
test_that("detect_duplicate_edges returns FALSE for no duplicates", {
edges <- data.frame(from = c(1, 2, 3), to = c(2, 3, 4), weight = c(0.5, 0.6, 0.7))
result <- detect_duplicate_edges(edges)
expect_false(result$has_duplicates)
expect_null(result$info)
})
test_that("detect_duplicate_edges detects simple duplicates", {
edges <- data.frame(from = c(1, 1, 2), to = c(2, 2, 3), weight = c(0.5, 0.3, 0.7))
result <- detect_duplicate_edges(edges)
expect_true(result$has_duplicates)
expect_length(result$info, 1)
expect_equal(result$info[[1]]$count, 2)
expect_equal(result$info[[1]]$weights, c(0.5, 0.3))
})
test_that("detect_duplicate_edges detects reversed duplicates in undirected mode", {
edges <- data.frame(from = c(1, 2, 2), to = c(2, 1, 3), weight = c(0.5, 0.3, 0.7))
result <- detect_duplicate_edges(edges)
expect_true(result$has_duplicates)
expect_length(result$info, 1)
expect_equal(result$info[[1]]$nodes, c(1, 2))
expect_equal(result$info[[1]]$count, 2)
})
test_that("detect_duplicate_edges handles NULL edges", {
result <- detect_duplicate_edges(NULL)
expect_false(result$has_duplicates)
expect_null(result$info)
})
test_that("detect_duplicate_edges handles empty data frame", {
edges <- data.frame(from = integer(0), to = integer(0))
result <- detect_duplicate_edges(edges)
expect_false(result$has_duplicates)
expect_null(result$info)
})
test_that("detect_duplicate_edges handles edges without weight column", {
edges <- data.frame(from = c(1, 1), to = c(2, 2))
result <- detect_duplicate_edges(edges)
expect_true(result$has_duplicates)
expect_equal(result$info[[1]]$weights, c(1, 1))
})
test_that("detect_duplicate_edges handles multiple duplicate groups", {
edges <- data.frame(
from = c(1, 1, 2, 2, 3),
to = c(2, 2, 3, 3, 4),
weight = c(0.1, 0.2, 0.3, 0.4, 0.5)
)
result <- detect_duplicate_edges(edges)
expect_true(result$has_duplicates)
expect_length(result$info, 2)
})
# =============================================================================
# aggregate_duplicate_edges() tests
# =============================================================================
test_that("aggregate_duplicate_edges with method='sum'", {
edges <- data.frame(from = c(1, 1, 2), to = c(2, 2, 3), weight = c(0.5, 0.3, 0.7))
result <- aggregate_duplicate_edges(edges, method = "sum")
expect_equal(nrow(result), 2)
expect_equal(result$weight[result$from == 1 & result$to == 2], 0.8)
})
test_that("aggregate_duplicate_edges with method='mean'", {
edges <- data.frame(from = c(1, 1, 2), to = c(2, 2, 3), weight = c(0.5, 0.3, 0.7))
result <- aggregate_duplicate_edges(edges, method = "mean")
expect_equal(result$weight[result$from == 1 & result$to == 2], 0.4)
})
test_that("aggregate_duplicate_edges with method='max'", {
edges <- data.frame(from = c(1, 1, 2), to = c(2, 2, 3), weight = c(0.5, 0.3, 0.7))
result <- aggregate_duplicate_edges(edges, method = "max")
expect_equal(result$weight[result$from == 1 & result$to == 2], 0.5)
})
test_that("aggregate_duplicate_edges with method='min'", {
edges <- data.frame(from = c(1, 1, 2), to = c(2, 2, 3), weight = c(0.5, 0.3, 0.7))
result <- aggregate_duplicate_edges(edges, method = "min")
expect_equal(result$weight[result$from == 1 & result$to == 2], 0.3)
})
test_that("aggregate_duplicate_edges with method='first'", {
edges <- data.frame(from = c(1, 1, 2), to = c(2, 2, 3), weight = c(0.5, 0.3, 0.7))
result <- aggregate_duplicate_edges(edges, method = "first")
expect_equal(result$weight[result$from == 1 & result$to == 2], 0.5)
})
test_that("aggregate_duplicate_edges with custom function", {
edges <- data.frame(from = c(1, 1, 2), to = c(2, 2, 3), weight = c(3, 4, 5))
result <- aggregate_duplicate_edges(edges, method = function(x) sqrt(sum(x^2)))
expect_equal(result$weight[result$from == 1 & result$to == 2], 5) # sqrt(9+16) = 5
})
test_that("aggregate_duplicate_edges errors on unknown method", {
edges <- data.frame(from = c(1, 1), to = c(2, 2), weight = c(0.5, 0.3))
expect_error(
aggregate_duplicate_edges(edges, method = "unknown"),
"Unknown aggregation method"
)
})
test_that("aggregate_duplicate_edges handles NULL edges", {
result <- aggregate_duplicate_edges(NULL)
expect_null(result)
})
test_that("aggregate_duplicate_edges handles empty data frame", {
edges <- data.frame(from = integer(0), to = integer(0), weight = numeric(0))
result <- aggregate_duplicate_edges(edges)
expect_equal(nrow(result), 0)
})
test_that("aggregate_duplicate_edges handles reversed duplicates", {
edges <- data.frame(from = c(1, 2), to = c(2, 1), weight = c(0.5, 0.3))
result <- aggregate_duplicate_edges(edges, method = "sum")
expect_equal(nrow(result), 1)
expect_equal(result$weight, 0.8)
# Should use canonical order (1 -> 2)
expect_equal(result$from, 1)
expect_equal(result$to, 2)
})
# =============================================================================
# parse_matrix() tests - Extended coverage
# =============================================================================
test_that("parse_matrix errors on non-matrix input", {
expect_error(parse_matrix(data.frame(a = 1:3)), "must be a matrix")
})
test_that("parse_matrix errors on non-numeric matrix", {
m <- matrix(c("a", "b", "c", "d"), nrow = 2)
expect_error(parse_matrix(m), "must be numeric")
})
test_that("parse_matrix uses colnames when rownames are NULL", {
m <- matrix(c(0, 1, 1, 0), nrow = 2)
colnames(m) <- c("X", "Y")
result <- parse_matrix(m)
expect_equal(result$nodes$label, c("X", "Y"))
})
test_that("parse_matrix generates labels when no dimnames", {
m <- matrix(c(0, 1, 1, 0), nrow = 2)
result <- parse_matrix(m)
expect_equal(result$nodes$label, c("1", "2"))
})
test_that("parse_matrix correctly extracts directed edges", {
m <- matrix(c(0, 1, 0, 0, 0, 1, 0, 0, 0), nrow = 3, byrow = TRUE)
result <- parse_matrix(m, directed = TRUE)
expect_true(result$directed)
# All non-zero entries should be edges
expect_equal(nrow(result$edges), 2)
})
test_that("parse_matrix correctly extracts undirected edges from upper triangle", {
m <- matrix(c(0, 1, 1, 1, 0, 1, 1, 1, 0), nrow = 3)
result <- parse_matrix(m, directed = FALSE)
expect_false(result$directed)
# Only upper triangle
expect_equal(nrow(result$edges), 3)
})
test_that("parse_matrix handles weighted matrix", {
m <- matrix(c(0, 0.5, 0.3, 0.5, 0, 0.8, 0.3, 0.8, 0), nrow = 3)
result <- parse_matrix(m)
expect_true(all(result$edges$weight %in% c(0.3, 0.5, 0.8)))
})
test_that("parse_matrix handles sparse matrix", {
m <- matrix(0, nrow = 5, ncol = 5)
m[1, 2] <- 1
m[2, 1] <- 1
result <- parse_matrix(m)
expect_equal(nrow(result$nodes), 5)
expect_equal(nrow(result$edges), 1) # Only upper triangle for symmetric
})
test_that("parse_matrix handles single node network", {
m <- matrix(0, nrow = 1, ncol = 1)
result <- parse_matrix(m)
expect_equal(nrow(result$nodes), 1)
expect_equal(nrow(result$edges), 0)
})
test_that("parse_matrix handles self-loops in directed network", {
m <- matrix(c(0.5, 1, 0, 0.5), nrow = 2)
result <- parse_matrix(m, directed = TRUE)
# Self-loops on diagonal
self_loops <- result$edges[result$edges$from == result$edges$to, ]
expect_true(nrow(self_loops) > 0)
})
# =============================================================================
# parse_edgelist() tests - Extended coverage
# =============================================================================
test_that("parse_edgelist errors on non-data.frame input", {
expect_error(parse_edgelist(matrix(1:4, 2)), "must be a data frame")
})
test_that("parse_edgelist auto-detects column names: source/target", {
df <- data.frame(source = c("A", "B"), target = c("B", "C"))
result <- parse_edgelist(df)
expect_equal(nrow(result$edges), 2)
})
test_that("parse_edgelist auto-detects column names: src/tgt", {
df <- data.frame(src = c("A", "B"), tgt = c("B", "C"))
result <- parse_edgelist(df)
expect_equal(nrow(result$edges), 2)
})
test_that("parse_edgelist auto-detects column names: v1/v2", {
df <- data.frame(v1 = c("A", "B"), v2 = c("B", "C"))
result <- parse_edgelist(df)
expect_equal(nrow(result$edges), 2)
})
test_that("parse_edgelist auto-detects column names: node1/node2", {
df <- data.frame(node1 = c("A", "B"), node2 = c("B", "C"))
result <- parse_edgelist(df)
expect_equal(nrow(result$edges), 2)
})
test_that("parse_edgelist auto-detects column names: i/j", {
df <- data.frame(i = c("A", "B"), j = c("B", "C"))
result <- parse_edgelist(df)
expect_equal(nrow(result$edges), 2)
})
test_that("parse_edgelist falls back to columns 1 and 2", {
df <- data.frame(col1 = c("A", "B"), col2 = c("B", "C"))
result <- parse_edgelist(df)
expect_equal(nrow(result$edges), 2)
})
test_that("parse_edgelist auto-detects weight column: w", {
df <- data.frame(from = c("A", "B"), to = c("B", "C"), w = c(0.5, 0.8))
result <- parse_edgelist(df)
expect_equal(result$weights, c(0.5, 0.8))
})
test_that("parse_edgelist auto-detects weight column: value", {
df <- data.frame(from = c("A", "B"), to = c("B", "C"), value = c(0.5, 0.8))
result <- parse_edgelist(df)
expect_equal(result$weights, c(0.5, 0.8))
})
test_that("parse_edgelist auto-detects weight column: strength", {
df <- data.frame(from = c("A", "B"), to = c("B", "C"), strength = c(0.5, 0.8))
result <- parse_edgelist(df)
expect_equal(result$weights, c(0.5, 0.8))
})
test_that("parse_edgelist handles numeric node IDs", {
df <- data.frame(from = c(1, 2, 3), to = c(2, 3, 1))
result <- parse_edgelist(df)
expect_equal(nrow(result$nodes), 3)
})
test_that("parse_edgelist auto-detects directed for bidirectional edges", {
# Edges 1->2 and 2->1 should indicate directed
df <- data.frame(from = c(1, 2), to = c(2, 1))
result <- parse_edgelist(df)
expect_true(result$directed)
})
test_that("parse_edgelist auto-detects undirected for simple edges", {
# No bidirectional edges
df <- data.frame(from = c(1, 2, 3), to = c(2, 3, 4))
result <- parse_edgelist(df)
expect_false(result$directed)
})
test_that("parse_edgelist respects explicit directed parameter", {
df <- data.frame(from = c(1, 2), to = c(2, 3))
result_directed <- parse_edgelist(df, directed = TRUE)
expect_true(result_directed$directed)
result_undirected <- parse_edgelist(df, directed = FALSE)
expect_false(result_undirected$directed)
})
test_that("parse_edgelist handles mixed character and numeric nodes", {
df <- data.frame(from = c("A", "B", "1"), to = c("B", "1", "A"))
result <- parse_edgelist(df)
expect_equal(nrow(result$nodes), 3)
expect_true(all(c("A", "B", "1") %in% result$nodes$label))
})
# =============================================================================
# Integration tests - parse_input with different formats
# =============================================================================
test_that("parse_input correctly identifies igraph objects", {
skip_if_not_installed("igraph")
g <- igraph::make_ring(5)
result <- parse_input(g)
expect_equal(nrow(result$nodes), 5)
expect_false(result$directed)
})
test_that("parse_input correctly identifies tna objects", {
# Create mock tna object
mock_tna <- list(
weights = matrix(c(0, 0.5, 0.1, 0.3, 0, 0.8, 0.7, 0.2, 0), nrow = 3),
labels = c("A", "B", "C"),
inits = c(0.3, 0.4, 0.3)
)
class(mock_tna) <- "tna"
result <- parse_input(mock_tna)
expect_equal(nrow(result$nodes), 3)
expect_true(result$directed)
})
# =============================================================================
# Edge cases and error handling
# =============================================================================
test_that("parse_matrix handles negative weights", {
m <- matrix(c(0, -0.5, 0.3, -0.5, 0, -0.8, 0.3, -0.8, 0), nrow = 3)
result <- parse_matrix(m)
expect_true(any(result$edges$weight < 0))
})
test_that("parse_matrix handles very small weights", {
m <- matrix(c(0, 1e-10, 1e-10, 0), nrow = 2)
result <- parse_matrix(m)
expect_equal(nrow(result$edges), 1)
})
test_that("parse_edgelist handles duplicate edges gracefully", {
df <- data.frame(
from = c("A", "A", "B"),
to = c("B", "B", "C"),
weight = c(0.5, 0.3, 0.8)
)
result <- parse_edgelist(df)
expect_equal(nrow(result$edges), 3) # Keeps all edges
})
test_that("create_nodes_df handles large number of nodes", {
result <- create_nodes_df(1000)
expect_equal(nrow(result), 1000)
expect_equal(result$id, 1:1000)
})
test_that("aggregate_duplicate_edges preserves row attributes", {
edges <- data.frame(
from = c(1, 1, 2),
to = c(2, 2, 3),
weight = c(0.5, 0.3, 0.7)
)
result <- aggregate_duplicate_edges(edges, method = "sum")
expect_equal(ncol(result), 3) # from, to, weight preserved
})
test_that("detect_duplicate_edges info contains correct node pairs", {
edges <- data.frame(
from = c(5, 10, 5),
to = c(10, 5, 10),
weight = c(0.1, 0.2, 0.3)
)
result <- detect_duplicate_edges(edges)
expect_true(result$has_duplicates)
# All three should map to 5-10
expect_equal(result$info[[1]]$nodes, c(5, 10))
expect_equal(result$info[[1]]$count, 3)
})
# =============================================================================
# Complex scenarios
# =============================================================================
test_that("parse_matrix handles fully connected network", {
n <- 4
m <- matrix(1, nrow = n, ncol = n)
diag(m) <- 0 # No self-loops
result <- parse_matrix(m)
expect_equal(nrow(result$nodes), 4)
# For undirected, upper triangle has n*(n-1)/2 edges
expect_equal(nrow(result$edges), 6)
})
test_that("parse_edgelist handles single edge network", {
df <- data.frame(from = "A", to = "B")
result <- parse_edgelist(df)
expect_equal(nrow(result$nodes), 2)
expect_equal(nrow(result$edges), 1)
})
test_that("parse_matrix with all zero weights returns empty edges", {
m <- matrix(0, nrow = 3, ncol = 3)
result <- parse_matrix(m)
expect_equal(nrow(result$nodes), 3)
expect_equal(nrow(result$edges), 0)
})
test_that("aggregate_duplicate_edges handles edges without weight column", {
edges <- data.frame(from = c(1, 1, 2), to = c(2, 2, 3))
result <- aggregate_duplicate_edges(edges, method = "sum")
# Should work even without weight column
expect_equal(nrow(result), 2)
})
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.