# Tests for communities.R - additional coverage tests (series 41)
# Focus on uncovered code paths, edge cases, and parameter variations

# ==============================================================================
# Test Setup
# ==============================================================================

# Create test networks with various properties
skip_coverage_tests()

set.seed(42)

# Small network for testing
mat_small <- matrix(c(
  0, 1, 1, 0, 0,
  1, 0, 1, 1, 0,
  1, 1, 0, 0, 1,
  0, 1, 0, 0, 1,
  0, 0, 1, 1, 0
), 5, 5, byrow = TRUE)
rownames(mat_small) <- colnames(mat_small) <- paste0("N", 1:5)

# Directed network
mat_directed <- matrix(c(
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1,
  1, 0, 0, 0
), 4, 4, byrow = TRUE)
rownames(mat_directed) <- colnames(mat_directed) <- LETTERS[1:4]

# Network with community structure (for consensus testing)
mat_community <- matrix(0, 12, 12)
mat_community[1:4, 1:4] <- 0.8
mat_community[5:8, 5:8] <- 0.8
mat_community[9:12, 9:12] <- 0.8
mat_community[4, 5] <- mat_community[5, 4] <- 0.1
mat_community[8, 9] <- mat_community[9, 8] <- 0.1
diag(mat_community) <- 0
rownames(mat_community) <- colnames(mat_community) <- paste0("N", 1:12)

# ==============================================================================
# Test communities() dispatch to additional methods
# ==============================================================================

test_that("communities() dispatches to infomap correctly", {
  skip_if_not_installed("igraph")

  comm <- communities(mat_small, method = "infomap")
  expect_s3_class(comm, "cograph_communities")
  expect_equal(attr(comm, "algorithm"), "infomap")
})

test_that("communities() dispatches to label_propagation correctly", {
  skip_if_not_installed("igraph")

  comm <- communities(mat_small, method = "label_propagation", seed = 42)
  expect_s3_class(comm, "cograph_communities")
  expect_equal(attr(comm, "algorithm"), "label_propagation")
})

test_that("communities() dispatches to edge_betweenness correctly", {
  skip_if_not_installed("igraph")

  comm <- communities(mat_small, method = "edge_betweenness")
  expect_s3_class(comm, "cograph_communities")
  expect_equal(attr(comm, "algorithm"), "edge_betweenness")
})

test_that("communities() dispatches to leading_eigenvector correctly", {
  skip_if_not_installed("igraph")

  comm <- communities(mat_small, method = "leading_eigenvector")
  expect_s3_class(comm, "cograph_communities")
  expect_equal(attr(comm, "algorithm"), "leading_eigenvector")
})

test_that("communities() dispatches to spinglass correctly", {
  skip_if_not_installed("igraph")

  # Need connected graph for spinglass
  g <- igraph::make_full_graph(8)
  comm <- communities(g, method = "spinglass", seed = 42)
  expect_s3_class(comm, "cograph_communities")
  expect_equal(attr(comm, "algorithm"), "spinglass")
})

test_that("communities() dispatches to optimal correctly", {
  skip_if_not_installed("igraph")

  mat_tiny <- matrix(c(0, 1, 1, 1, 0, 1, 1, 1, 0), 3, 3)
  comm <- communities(mat_tiny, method = "optimal")
  expect_s3_class(comm, "cograph_communities")
  expect_equal(attr(comm, "algorithm"), "optimal")
})

test_that("communities() dispatches to fluid correctly", {
  skip_if_not_installed("igraph")

  g <- igraph::make_full_graph(10)
  comm <- communities(g, method = "fluid", no.of.communities = 2)
  expect_s3_class(comm, "cograph_communities")
  expect_equal(attr(comm, "algorithm"), "fluid")
})

# ==============================================================================
# Test community_leiden with additional parameters
# ==============================================================================

test_that("community_leiden works with initial_membership", {
  skip_if_not_installed("igraph")

  # Initial membership: all nodes start in same community
  initial <- rep(1, 12)
  comm <- community_leiden(mat_community, initial_membership = initial, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_leiden works with vertex_weights", {
  skip_if_not_installed("igraph")

  vertex_weights <- rep(1, 12)
  comm <- community_leiden(mat_community, vertex_weights = vertex_weights, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_leiden works with n_iterations = -1 for convergence", {
  skip_if_not_installed("igraph")

  comm <- community_leiden(mat_small, n_iterations = -1, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test community_infomap with additional parameters
# ==============================================================================

test_that("community_infomap works with v.weights", {
  skip_if_not_installed("igraph")

  v_weights <- rep(1, 5)
  comm <- community_infomap(mat_small, v.weights = v_weights, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_infomap works with modularity = FALSE", {
  skip_if_not_installed("igraph")

  comm <- community_infomap(mat_small, modularity = FALSE, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test community_label_propagation with additional parameters
# ==============================================================================

test_that("community_label_propagation works with mode = 'in'", {
  skip_if_not_installed("igraph")

  comm <- community_label_propagation(mat_directed, mode = "in", seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_label_propagation works with initial labels", {
  skip_if_not_installed("igraph")

  g <- igraph::make_graph("Zachary")
  n <- igraph::vcount(g)

  # Provide initial labels for all nodes
  initial <- seq_len(n)
  comm <- community_label_propagation(g, initial = initial, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_label_propagation works with fixed labels", {
  skip_if_not_installed("igraph")

  g <- igraph::make_graph("Zachary")
  n <- igraph::vcount(g)

  # Fix first two nodes to specific communities
  initial <- seq_len(n)
  fixed <- rep(FALSE, n)
  fixed[c(1, 34)] <- TRUE

  comm <- community_label_propagation(g, initial = initial, fixed = fixed, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test community_edge_betweenness with additional parameters
# ==============================================================================

test_that("community_edge_betweenness with directed = NULL auto-detects", {
  skip_if_not_installed("igraph")

  comm <- community_edge_betweenness(mat_small, directed = NULL)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_edge_betweenness with edge.betweenness = FALSE", {
  skip_if_not_installed("igraph")

  comm <- community_edge_betweenness(mat_small, edge.betweenness = FALSE)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_edge_betweenness with bridges = FALSE", {
  skip_if_not_installed("igraph")

  comm <- community_edge_betweenness(mat_small, bridges = FALSE)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_edge_betweenness with modularity = FALSE", {
  skip_if_not_installed("igraph")

  comm <- community_edge_betweenness(mat_small, modularity = FALSE)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_edge_betweenness with merges = FALSE", {
  skip_if_not_installed("igraph")

  comm <- community_edge_betweenness(mat_small, merges = FALSE)
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test community_leading_eigenvector with additional parameters
# ==============================================================================

test_that("community_leading_eigenvector with start parameter", {
  skip_if_not_installed("igraph")

  # Start with all nodes in one community
  start <- rep(1, 5)
  comm <- community_leading_eigenvector(mat_small, start = start)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_leading_eigenvector with callback function", {
  skip_if_not_installed("igraph")

  # Simple callback that does nothing (accept ... for igraph version compat)
  callback_count <- 0
  my_callback <- function(membership, comm, ...) {
    callback_count <<- callback_count + 1
    return(FALSE)  # Continue
  }

  comm <- community_leading_eigenvector(mat_small, callback = my_callback)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_leading_eigenvector with extra parameter", {
  skip_if_not_installed("igraph")

  my_callback <- function(membership, comm, ...) {
    return(FALSE)
  }

  comm <- community_leading_eigenvector(mat_small, callback = my_callback)
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test community_spinglass with additional parameters
# ==============================================================================

test_that("community_spinglass with vertex parameter for single community mode", {
  skip_if_not_installed("igraph")

  g <- igraph::make_full_graph(10)

  # Find community containing vertex 1
  result <- community_spinglass(g, vertex = 1, seed = 42)
  # When vertex is specified, result is different structure
  expect_true(!is.null(result))
})

test_that("community_spinglass with parupdate = TRUE", {
  skip_if_not_installed("igraph")

  g <- igraph::make_full_graph(10)
  comm <- community_spinglass(g, parupdate = TRUE, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_spinglass with custom temperature parameters", {
  skip_if_not_installed("igraph")

  g <- igraph::make_full_graph(10)
  comm <- community_spinglass(g,
                              start.temp = 2,
                              stop.temp = 0.001,
                              cool.fact = 0.95,
                              seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_spinglass with update.rule = 'random'", {
  skip_if_not_installed("igraph")

  g <- igraph::make_full_graph(10)
  comm <- community_spinglass(g, update.rule = "random", seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_spinglass with gamma parameter", {
  skip_if_not_installed("igraph")

  g <- igraph::make_full_graph(10)
  comm <- community_spinglass(g, gamma = 0.5, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_spinglass with implementation = 'neg'", {
  skip_if_not_installed("igraph")

  g <- igraph::make_full_graph(10)
  comm <- community_spinglass(g, implementation = "neg", gamma.minus = 0.5, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test community_consensus with additional methods
# ==============================================================================

test_that("community_consensus works with infomap", {
  skip_if_not_installed("igraph")

  comm <- community_consensus(mat_community, method = "infomap", n_runs = 2, seed = 42)
  expect_s3_class(comm, "cograph_communities")
  expect_true(grepl("consensus_infomap", attr(comm, "algorithm")))
})

test_that("community_consensus works with label_propagation", {
  skip_if_not_installed("igraph")

  comm <- community_consensus(mat_community, method = "label_propagation", n_runs = 2, seed = 42)
  expect_s3_class(comm, "cograph_communities")
  expect_true(grepl("consensus_label_propagation", attr(comm, "algorithm")))
})

test_that("community_consensus works with spinglass on connected graph", {
  skip_if_not_installed("igraph")

  # Need fully connected graph for spinglass
  g <- igraph::make_full_graph(10)
  comm <- community_consensus(g, method = "spinglass", n_runs = 2, seed = 42)
  expect_s3_class(comm, "cograph_communities")
  expect_true(grepl("consensus_spinglass", attr(comm, "algorithm")))
})

test_that("community_consensus preserves node names", {
  skip_if_not_installed("igraph")

  g <- igraph::make_graph("Zachary")
  igraph::V(g)$name <- paste0("Node", seq_len(igraph::vcount(g)))

  comm <- community_consensus(g, n_runs = 2, seed = 42)
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test print.cograph_communities edge cases
# ==============================================================================

test_that("print.cograph_communities works with unnamed nodes", {
  skip_if_not_installed("igraph")

  # Matrix without rownames
  mat_unnamed <- matrix(c(0, 1, 1, 1, 0, 1, 1, 1, 0), 3, 3)
  comm <- community_louvain(mat_unnamed)

  output <- capture.output(print(comm))
  expect_true(any(grepl("louvain", output)))
})

test_that("print.cograph_communities shows node count when names available", {
  skip_if_not_installed("igraph")

  comm <- community_louvain(mat_small)
  output <- capture.output(print(comm))

  expect_true(any(grepl("Nodes", output)))
})

test_that("print returns invisible object", {
  skip_if_not_installed("igraph")

  comm <- community_louvain(mat_small)
  result <- print(comm)

  expect_identical(result, comm)
})

# ==============================================================================
# Test membership.cograph_communities edge cases
# ==============================================================================

test_that("membership returns named vector with auto-generated labels for unnamed graph", {
  skip_if_not_installed("igraph")

  mat_unnamed <- matrix(c(0, 1, 1, 1, 0, 1, 1, 1, 0), 3, 3)
  comm <- community_louvain(mat_unnamed)
  mem <- membership(comm)

  expect_true(is.numeric(mem))
  # Auto-generated labels are assigned even for unnamed graphs
  expect_true(!is.null(names(mem)))
  expect_equal(length(mem), 3)
})

# ==============================================================================
# Test modularity.cograph_communities edge cases
# ==============================================================================

test_that("modularity.cograph_communities handles stored modularity vector", {
  skip_if_not_installed("igraph")

  # Fast greedy returns modularity as vector
  comm <- community_fast_greedy(mat_community)
  mod <- modularity.cograph_communities(comm)

  expect_true(is.numeric(mod))
  expect_length(mod, 1)
})

test_that("modularity.cograph_communities handles missing modularity gracefully", {
  skip_if_not_installed("igraph")

  # Create minimal communities object
  g <- igraph::make_ring(5)
  result <- igraph::cluster_louvain(g)
  wrapped <- cograph:::.wrap_communities(result, "test", g)

  # Should still work via method dispatch
  mod <- modularity.cograph_communities(wrapped)
  expect_true(is.numeric(mod) || is.na(mod))
})

# ==============================================================================
# Test compare_communities additional methods
# ==============================================================================

test_that("compare_communities works with split.join method", {
  skip_if_not_installed("igraph")

  comm1 <- community_louvain(mat_community, seed = 1)
  comm2 <- community_leiden(mat_community, seed = 1)

  sj <- compare_communities(comm1, comm2, method = "split.join")
  expect_true(is.numeric(sj))
  expect_true(sj >= 0)
})

# ==============================================================================
# Test plot.cograph_communities
# ==============================================================================

test_that("plot.cograph_communities works with network", {
  skip_if_not_installed("igraph")

  comm <- community_louvain(mat_community)
  net <- as_cograph(mat_community)

  with_temp_png({
    plot(comm, network = net)
  })

  expect_true(TRUE)  # If we got here, plot succeeded
})

test_that("plot.cograph_communities passes additional arguments to splot", {
  skip_if_not_installed("igraph")

  comm <- community_louvain(mat_community)
  net <- as_cograph(mat_community)

  with_temp_png({
    plot(comm, network = net, title = "Test Communities")
  })

  expect_true(TRUE)
})

# ==============================================================================
# Test community_walktrap additional parameters
# ==============================================================================

test_that("community_walktrap with merges = FALSE", {
  skip_if_not_installed("igraph")

  comm <- community_walktrap(mat_small, merges = FALSE)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_walktrap with modularity = FALSE", {
  skip_if_not_installed("igraph")

  comm <- community_walktrap(mat_small, modularity = FALSE)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_walktrap with membership = FALSE", {
  skip_if_not_installed("igraph")

  # When membership = FALSE, we still get the structure
  comm <- community_walktrap(mat_small, membership = FALSE)
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test community_fast_greedy additional parameters
# ==============================================================================

test_that("community_fast_greedy with merges = FALSE", {
  skip_if_not_installed("igraph")

  comm <- community_fast_greedy(mat_small, merges = FALSE)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_fast_greedy with modularity = FALSE", {
  skip_if_not_installed("igraph")

  comm <- community_fast_greedy(mat_small, modularity = FALSE)
  expect_s3_class(comm, "cograph_communities")
})

test_that("community_fast_greedy with membership = FALSE", {
  skip_if_not_installed("igraph")

  comm <- community_fast_greedy(mat_small, membership = FALSE)
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test with igraph objects directly
# ==============================================================================

test_that("all methods work with igraph input", {
  skip_if_not_installed("igraph")

  g <- igraph::make_graph("Zachary")

  # Test several methods with igraph input
  expect_s3_class(community_louvain(g), "cograph_communities")
  expect_s3_class(community_leiden(g), "cograph_communities")
  expect_s3_class(community_walktrap(g), "cograph_communities")
  expect_s3_class(community_fast_greedy(g), "cograph_communities")
  expect_s3_class(community_infomap(g), "cograph_communities")
  expect_s3_class(community_label_propagation(g), "cograph_communities")
  expect_s3_class(community_edge_betweenness(g), "cograph_communities")
  expect_s3_class(community_leading_eigenvector(g), "cograph_communities")
})

# ==============================================================================
# Test n_communities and community_sizes edge cases
# ==============================================================================

test_that("n_communities works with single community", {
  skip_if_not_installed("igraph")

  # Small fully connected graph likely has single community
  mat_full <- matrix(1, 3, 3)
  diag(mat_full) <- 0
  comm <- community_louvain(mat_full)

  n <- n_communities(comm)
  expect_true(is.numeric(n))
  expect_true(n >= 1)
})

test_that("community_sizes returns integer vector", {
  skip_if_not_installed("igraph")

  comm <- community_louvain(mat_community)
  sizes <- community_sizes(comm)

  expect_true(is.integer(sizes))
  expect_true(all(sizes > 0))
})

# ==============================================================================
# Test .resolve_weights edge cases
# ==============================================================================
test_that(".resolve_weights handles length-1 NA correctly", {
  skip_if_not_installed("igraph")

  g <- igraph::make_ring(5)
  igraph::E(g)$weight <- c(1, 2, 3, 4, 5)

  # NA should return NULL even if graph has weights
  result <- cograph:::.resolve_weights(g, NA)
  expect_null(result)
})

test_that(".resolve_weights returns custom weights unchanged", {
  skip_if_not_installed("igraph")

  g <- igraph::make_ring(5)
  igraph::E(g)$weight <- c(1, 2, 3, 4, 5)

  custom <- c(10, 20, 30, 40, 50)
  result <- cograph:::.resolve_weights(g, custom)
  expect_equal(result, custom)
})

# ==============================================================================
# Test .wrap_communities edge cases
# ==============================================================================

test_that(".wrap_communities handles unnamed graph", {
  skip_if_not_installed("igraph")

  g <- igraph::make_ring(5)  # No names set
  result <- igraph::cluster_louvain(g)
  wrapped <- cograph:::.wrap_communities(result, "test", g)

  expect_s3_class(wrapped, "cograph_communities")
  # Unnamed graph gets auto-generated node labels as character strings
  expect_true("node" %in% names(wrapped))
})

test_that(".wrap_communities adds class correctly", {
  skip_if_not_installed("igraph")

  g <- igraph::make_ring(5)
  result <- igraph::cluster_louvain(g)
  wrapped <- cograph:::.wrap_communities(result, "louvain", g)

  expect_true("cograph_communities" %in% class(wrapped))
  expect_true("data.frame" %in% class(wrapped))
})

# ==============================================================================
# Test cograph_network input conversion
# ==============================================================================

test_that("communities work with cograph_network input via to_igraph", {
  skip_if_not_installed("igraph")

  net <- as_cograph(mat_community)

  # All major methods should work
  expect_s3_class(communities(net, method = "louvain"), "cograph_communities")
  expect_s3_class(communities(net, method = "leiden"), "cograph_communities")
  expect_s3_class(communities(net, method = "walktrap"), "cograph_communities")
})

# ==============================================================================
# Test directed vs undirected handling
# ==============================================================================

test_that("community_louvain errors on directed input", {
  skip_if_not_installed("igraph")

  g <- igraph::make_ring(10, directed = TRUE)
  expect_error(community_louvain(g))
})

test_that("community_leiden errors on directed input", {
  skip_if_not_installed("igraph")

  g <- igraph::make_ring(10, directed = TRUE)
  expect_error(community_leiden(g))
})

test_that("community_infomap handles directed input well", {
  skip_if_not_installed("igraph")

  g <- igraph::make_ring(10, directed = TRUE)
  comm <- community_infomap(g)
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test weighted networks
# ==============================================================================

test_that("communities detect weighted networks automatically", {
  skip_if_not_installed("igraph")

  # Create weighted igraph
  g <- igraph::make_ring(10)
  igraph::E(g)$weight <- runif(igraph::ecount(g))

  comm <- community_louvain(g)  # Should use weights automatically
  expect_s3_class(comm, "cograph_communities")
})

test_that("weights = NA forces unweighted analysis", {
  skip_if_not_installed("igraph")

  # Create weighted igraph
  g <- igraph::make_ring(10)
  igraph::E(g)$weight <- runif(igraph::ecount(g))

  comm <- community_louvain(g, weights = NA)  # Should ignore weights
  expect_s3_class(comm, "cograph_communities")
})

# ==============================================================================
# Test error handling
# ==============================================================================

test_that("community_fluid requires no.of.communities", {
  skip_if_not_installed("igraph")

  g <- igraph::make_full_graph(10)
  expect_error(community_fluid(g), "no.of.communities is required")
})

test_that("plot.cograph_communities requires network argument when not stored", {
  skip_if_not_installed("igraph")

  # Build a bare cograph_communities without stored network
  bare <- data.frame(node = paste0("N", 1:3), community = c(1L, 1L, 2L),
                     stringsAsFactors = FALSE)
  class(bare) <- c("cograph_communities", "data.frame")
  expect_error(plot(bare), "No network found")
})

# ==============================================================================
# Test community_optimal warning
# ==============================================================================

test_that("community_optimal warns on large network", {
  skip_if_not_installed("igraph")

  # Create network larger than 50 nodes (but small enough to actually compute)
  # Use sparse 51-node ring to trigger warning without excessive computation
  g <- igraph::make_ring(51)
  mat_large <- as.matrix(igraph::as_adjacency_matrix(g))

  expect_warning(community_optimal(mat_large), "50 nodes")
})

# ==============================================================================
# Test community_fluid disconnected graph warning
# ==============================================================================

test_that("community_fluid warns and uses largest component", {
  skip_if_not_installed("igraph")

  # Create disconnected graph
  g1 <- igraph::make_full_graph(5)
  g2 <- igraph::make_full_graph(5)
  g <- g1 + g2  # Disconnected

  expect_warning(community_fluid(g, no.of.communities = 2), "connected")
})

# ==============================================================================
# Test community_spinglass disconnected graph warning
# ==============================================================================

test_that("community_spinglass warns and uses largest component", {
  skip_if_not_installed("igraph")

  # Create disconnected graph
  g1 <- igraph::make_full_graph(5)
  g2 <- igraph::make_full_graph(5)
  g <- g1 + g2  # Disconnected

  expect_warning(community_spinglass(g, seed = 42), "connected")
})

# ==============================================================================
# Test seed reproducibility
# ==============================================================================

test_that("louvain is reproducible with seed", {
  skip_if_not_installed("igraph")

  comm1 <- community_louvain(mat_community, seed = 42)
  comm2 <- community_louvain(mat_community, seed = 42)

  expect_equal(comm1$community, comm2$community)
})

test_that("leiden is reproducible with seed", {
  skip_if_not_installed("igraph")

  comm1 <- community_leiden(mat_community, seed = 42)
  comm2 <- community_leiden(mat_community, seed = 42)

  expect_equal(comm1$community, comm2$community)
})

test_that("infomap is reproducible with seed", {
  skip_if_not_installed("igraph")

  comm1 <- community_infomap(mat_community, seed = 42)
  comm2 <- community_infomap(mat_community, seed = 42)

  expect_equal(comm1$community, comm2$community)
})

test_that("label_propagation is reproducible with seed", {
  skip_if_not_installed("igraph")

  comm1 <- community_label_propagation(mat_community, seed = 42)
  comm2 <- community_label_propagation(mat_community, seed = 42)

  expect_equal(comm1$community, comm2$community)
})

test_that("spinglass is reproducible with seed", {
  skip_if_not_installed("igraph")

  g <- igraph::make_full_graph(10)
  comm1 <- community_spinglass(g, seed = 42)
  comm2 <- community_spinglass(g, seed = 42)

  expect_equal(comm1$community, comm2$community)
})

# ==============================================================================
# Test all short aliases work correctly
# ==============================================================================

test_that("all com_* aliases produce correct algorithm", {
  skip_if_not_installed("igraph")

  g <- igraph::make_full_graph(10)
  mat_tiny <- matrix(c(0, 1, 1, 1, 0, 1, 1, 1, 0), 3, 3)

  expect_equal(attr(com_lv(mat_small), "algorithm"), "louvain")
  expect_equal(attr(com_ld(mat_small), "algorithm"), "leiden")
  expect_equal(attr(com_fg(mat_small), "algorithm"), "fast_greedy")
  expect_equal(attr(com_wt(mat_small), "algorithm"), "walktrap")
  expect_equal(attr(com_im(mat_small), "algorithm"), "infomap")
  expect_equal(attr(com_lp(mat_small), "algorithm"), "label_propagation")
  expect_equal(attr(com_eb(mat_small), "algorithm"), "edge_betweenness")
  expect_equal(attr(com_le(mat_small), "algorithm"), "leading_eigenvector")
  expect_equal(attr(com_sg(g, seed = 42), "algorithm"), "spinglass")
  expect_equal(attr(com_op(mat_tiny), "algorithm"), "optimal")
  expect_equal(attr(com_fl(g, no.of.communities = 2), "algorithm"), "fluid")
  expect_true(grepl("consensus", attr(com_consensus(mat_small, n_runs = 2), "algorithm")))
})

# ==============================================================================
# Summary
# ==============================================================================

cat("\n=== All Community Detection Coverage Tests (Series 41) Passed ===\n")
