From e3137151a8c10a3ef8f5b308e63d8816a27c5889 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 10:03:34 +0000 Subject: [PATCH 1/2] test: Pin C core behaviour that the vendoring series changes Each test passes with the vendored C core 0.10.17 and fails with 1.0.1+, so the vendor commit that changes the behaviour has to flip the expectation, and every user-visible change shows up in the review diff. Pinned: `hits_scores()` on edgeless and undirected graphs, `eigen_centrality()` on disconnected graphs, the `cluster_infomap()` code length, the edge order of `graph_from_adjacency_matrix()` and `graph_from_biadjacency_matrix()`, and the random streams of `sample_islands()`, `layout_with_gem()` and `layout_with_dh()`. The ARPACK error wording is already pinned by an existing snapshot. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016jy2KuQGnR2SqMEUJ3dx35 --- tests/testthat/test-adjacency.R | 7 +++++++ tests/testthat/test-centrality.R | 25 +++++++++++++++++++++++++ tests/testthat/test-community.R | 7 +++++++ tests/testthat/test-games.R | 10 ++++++++++ tests/testthat/test-incidence.R | 7 +++++++ tests/testthat/test-layout.R | 22 ++++++++++++++++++++++ 6 files changed, 78 insertions(+) diff --git a/tests/testthat/test-adjacency.R b/tests/testthat/test-adjacency.R index f2758cdde27..629de73a480 100644 --- a/tests/testthat/test-adjacency.R +++ b/tests/testthat/test-adjacency.R @@ -1002,3 +1002,10 @@ test_that("from_adjacency() covers tail args by name and recovers positional cal make_(from_adjacency(M, mode = "undirected")) ) }) + +test_that("graph_from_adjacency_matrix() creates edges row by row", { + # Pins the edge order of the C core for directed input. + m <- matrix(c(0, 1, 1, 1, 0, 1, 0, 0, 0), 3) + g <- graph_from_adjacency_matrix(m) + expect_equal(as_edgelist(g), rbind(c(1, 2), c(2, 1), c(3, 1), c(3, 2))) +}) diff --git a/tests/testthat/test-centrality.R b/tests/testthat/test-centrality.R index 3e36af6a327..7158422bf3c 100644 --- a/tests/testthat/test-centrality.R +++ b/tests/testthat/test-centrality.R @@ -1258,3 +1258,28 @@ test_that("alpha_centrality() covers migrated tail args and positional recovery" ) expect_identical(res_legacy, alpha_centrality(dag, V(dag), alpha = 0.75)) }) + +# ---- C core behaviour pins ---------------------------------------------- +# These pin the behaviour of the vendored C core, +# so that the vendor commit that changes it also flips the expectation. + +test_that("hits_scores() on an edgeless graph gives NaN silently", { + g <- make_empty_graph(3) + expect_silent(res <- hits_scores(g)) + expect_identical(res$value, NaN) +}) + +test_that("hits_scores() on an undirected graph does not warn", { + expect_silent(res <- hits_scores(make_ring(3))) + expect_equal(res$value, 4) +}) + +test_that("eigen_centrality() on a disconnected graph does not warn", { + g <- make_star(3, mode = "undirected") + make_ring(3) + expect_silent(res <- eigen_centrality(g)) + expect_equal(res$vector, c(0, 0, 0, 1, 1, 1)) + + g <- make_ring(3) + make_ring(4) + expect_silent(res <- eigen_centrality(g)) + expect_equal(res$vector, rep(1, 7), tolerance = 1e-5) +}) diff --git a/tests/testthat/test-community.R b/tests/testthat/test-community.R index 66123bbc5e2..33830c52057 100644 --- a/tests/testthat/test-community.R +++ b/tests/testthat/test-community.R @@ -1042,3 +1042,10 @@ test_that("modularity_matrix() covers migrated tail args and positional recovery modularity_matrix(karate, rep(1, vcount(karate)), rep(1, ecount(karate))) }) }) + +test_that("cluster_infomap() code length on the karate graph", { + # Pins the vendored Infomap implementation. + karate <- make_graph("Zachary") + res <- cluster_infomap(karate, nb.trials = 1) + expect_equal(code_len(res), 4.606059, tolerance = 1e-6) +}) diff --git a/tests/testthat/test-games.R b/tests/testthat/test-games.R index 58a491d9ca9..22356e0b733 100644 --- a/tests/testthat/test-games.R +++ b/tests/testthat/test-games.R @@ -1770,3 +1770,13 @@ test_that("sample_correlated_gnp() recovers positional p", { sample_correlated_gnp(base_graph, 0.8, p = 0.3) ) }) + +test_that("sample_islands() random stream for a fixed seed", { + # Pins the random numbers the C core draws for this generator. + igraph_local_seed(42) + g <- sample_islands(2, 3, 0.5, 1) + expect_equal( + as_edgelist(g), + rbind(c(1, 3), c(2, 3), c(3, 6), c(4, 5), c(4, 6)) + ) +}) diff --git a/tests/testthat/test-incidence.R b/tests/testthat/test-incidence.R index 90646d23f5d..490c383049c 100644 --- a/tests/testthat/test-incidence.R +++ b/tests/testthat/test-incidence.R @@ -251,3 +251,10 @@ test_that("graph_from_biadjacency_matrix() covers add.names by name and recovers ) expect_true(is_directed(res)) }) + +test_that("graph_from_biadjacency_matrix() creates edges row by row", { + # Pins the edge order of the C core for dense unweighted input. + m <- matrix(c(1, 1, 1, 0), 2) + g <- graph_from_biadjacency_matrix(m) + expect_equal(as_edgelist(g), rbind(c(1, 3), c(1, 4), c(2, 3))) +}) diff --git a/tests/testthat/test-layout.R b/tests/testthat/test-layout.R index 5e66612b815..eca260de8b5 100644 --- a/tests/testthat/test-layout.R +++ b/tests/testthat/test-layout.R @@ -945,3 +945,25 @@ test_that("norm_coords() recovers positional calls", { # xmin = 0 rescales the first column into [0, 1]. expect_equal(range(res[, 1]), c(0, 1)) }) + +test_that("layout_with_gem() random stream for a fixed seed", { + # Pins the random numbers the C core draws for this layout. + igraph_local_seed(42) + l <- layout_with_gem(make_ring(3)) + expect_equal( + l, + cbind(c(130.218, -34.753, 88.118), c(238.780, 196.748, 71.715)), + tolerance = 1e-4 + ) +}) + +test_that("layout_with_dh() random stream for a fixed seed", { + # Pins the random numbers the C core draws for this layout. + igraph_local_seed(42) + l <- layout_with_dh(make_ring(3)) + expect_equal( + l, + cbind(c(0.444, -1.310, -0.350), c(-7.937, -7.812, -6.384)), + tolerance = 1e-3 + ) +}) From 9310090d47d169afed102d8a17a91de75cf14005 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 10:01:43 +0000 Subject: [PATCH 2/2] test: Expect the near-zero warnings in the `eigen_centrality()` stress test Most random graphs in the stress test are disconnected, so `eigen_centrality()` warns that some centralities are nearly zero, which emitted hundreds of warnings on a passing test. The test now checks that only this warning occurs and muffles it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01L5n6BLiYoPmk3NFiYDSKZZ --- tests/testthat/test-centrality.R | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-centrality.R b/tests/testthat/test-centrality.R index 7158422bf3c..0461860497d 100644 --- a/tests/testthat/test-centrality.R +++ b/tests/testthat/test-centrality.R @@ -594,9 +594,20 @@ test_that("eigen_centrality() works", { expect_ev(M, v, lambda, eps) } + # Most of these graphs are disconnected, and warn that some centralities + # are nearly zero; no other warning is expected. for (i in 1:1000) { G <- sample_gnm(10, sample(1:20, 1)) - ev <- eigen_centrality(G) + ev <- withCallingHandlers( + eigen_centrality(G), + warning = function(w) { + expect_match( + conditionMessage(w), + "eigenvector centralities are nearly zero" + ) + invokeRestart("muffleWarning") + } + ) expect_good( as_adjacency_matrix(G, sparse = FALSE), ev$vector,