diff --git a/R/par.R b/R/par.R index 419c7e64384..0b37a47d5b2 100644 --- a/R/par.R +++ b/R/par.R @@ -77,19 +77,19 @@ igraph.pars.set.verbose <- function(verbose) { .Call(R_igraph_set_verbose, verbose) } else if (is.character(verbose)) { if (!verbose %in% c("tk", "tkconsole")) { - stop("Unknown 'verbose' value") + cli::cli_abort("Unknown {.arg verbose} value.") } if (verbose %in% c("tk", "tkconsole")) { if (!capabilities()[["X11"]]) { - stop("X11 not available") + cli::cli_abort("X11 not available.") } if (!requireNamespace("tcltk", quietly = TRUE)) { - stop("tcltk package not available") + cli::cli_abort("tcltk package not available.") } } .Call(R_igraph_set_verbose, TRUE) } else { - stop("'verbose' should be a logical or character scalar") + cli::cli_abort("{.arg verbose} should be a logical or character scalar.") } verbose } @@ -209,7 +209,7 @@ igraph_i_options <- function(..., .in = parent.frame()) { switch(mode(arg), list = temp <- arg, character = return(.igraph.pars[arg]), - stop("invalid argument: ", sQuote(arg)) + cli::cli_abort("invalid argument: {arg}.") ) } if (length(temp) == 0) { @@ -218,7 +218,7 @@ igraph_i_options <- function(..., .in = parent.frame()) { ## Callbacks n <- names(temp) - if (is.null(n)) stop("options must be given by name") + if (is.null(n)) cli::cli_abort("options must be given by name.") cb <- intersect(names(igraph.pars.callbacks), n) for (cn in cb) { temp[[cn]] <- igraph.pars.callbacks[[cn]](temp[[cn]]) diff --git a/R/sparsedf.R b/R/sparsedf.R index 40fbcf03822..979747eaba8 100644 --- a/R/sparsedf.R +++ b/R/sparsedf.R @@ -28,24 +28,24 @@ sdf <- function(..., row.names = NULL, NROW = NULL) { if (is.null(names(cols)) || any(names(cols) == "") || any(duplicated(names(cols)))) { - stop("Columns must be have (unique) names") + cli::cli_abort("Columns must be have (unique) names.") } lens <- sapply(cols, length) n1lens <- lens[lens != 1] if (length(unique(n1lens)) > 1) { - stop("Columns must be constants or have the same length") + cli::cli_abort("Columns must be constants or have the same length.") } if (length(n1lens) == 0) { if (is.null(NROW)) { - stop("Cannot determine number of rows") + cli::cli_abort("Cannot determine number of rows.") } attr(cols, "NROW") <- NROW } else { if (!is.null(NROW) && n1lens[1] != NROW) { - stop("NROW does not match column lengths") + cli::cli_abort("{.arg NROW} does not match column lengths.") } attr(cols, "NROW") <- unname(n1lens[1]) } @@ -64,10 +64,10 @@ as.data.frame.igraphSDF <- function(x, row.names, optional, ...) { #' @method "[" igraphSDF `[.igraphSDF` <- function(x, i, j, ..., drop = TRUE) { if (!is.character(j)) { - stop("The column index must be character") + cli::cli_abort("The column index must be character.") } if (!missing(i) && !is.numeric(i)) { - stop("The row index must be numeric") + cli::cli_abort("The row index must be numeric.") } if (missing(i)) { rep(x[[j]], length.out = attr(x, "NROW")) @@ -83,19 +83,19 @@ as.data.frame.igraphSDF <- function(x, row.names, optional, ...) { #' @method "[<-" igraphSDF `[<-.igraphSDF` <- function(x, i, j, value) { if (!is.character(j)) { - stop("The column index must be character") + cli::cli_abort("The column index must be character.") } if (!missing(i) && !is.numeric(i)) { - stop("Row index must be numeric, if given") + cli::cli_abort("Row index must be numeric, if given.") } if (missing(i)) { if (length(value) != attr(x, "NROW") && length(value) != 1) { - stop("Replacement value has the wrong length") + cli::cli_abort("Replacement value has the wrong length.") } x[[j]] <- value } else { if (length(value) != length(i) && length(value) != 1) { - stop("Replacement value has the wrong length") + cli::cli_abort("Replacement value has the wrong length.") } tmp <- rep(x[[j]], length.out = attr(x, "NROW")) tmp[i] <- value diff --git a/tests/testthat/_snaps/print.md b/tests/testthat/_snaps/print.md index e431606cdd6..f2fa7386b87 100644 --- a/tests/testthat/_snaps/print.md +++ b/tests/testthat/_snaps/print.md @@ -6,3 +6,122 @@ + 1/1 edge (vertex names): [1] A->B +# vs printing + + Code + V(g)[[1]] + Output + + 1/3 vertex, named: + name color weight + 1 A red 10 + Code + V(g)[[2]] + Output + + 1/3 vertex, named: + name color weight + 2 B red 9 + Code + V(g)[1:2] + Output + + 2/3 vertices, named: + [1] A B + Code + V(g)[2:3] + Output + + 2/3 vertices, named: + [1] B C + +# vs printing, complex attributes + + Code + V(g)[[1]] + Output + + 1/3 vertex, named: + $name + [1] "A" + + $color + [1] "red" + + $weight + [1] 10 + + $cplx + $cplx[[1]] + [1] 1 2 3 4 + + + Code + V(g)[[2:3]] + Output + + 2/3 vertices, named: + $name + [1] "B" "C" + + $color + [1] "red" "red" + + $weight + [1] 9 3 + + $cplx + $cplx[[1]] + [1] 1 2 3 4 + + $cplx[[2]] + [1] 1 2 3 4 + + + +# es printing + + Code + E(g)[[1]] + Output + + 1/3 edge (vertex names): + tail head tid hid color weight + 1 A B 1 2 red 10 + Code + E(g)[[2:3]] + Output + + 2/3 edges (vertex names): + tail head tid hid color weight + 2 A C 1 3 red 9 + 3 B C 2 3 red 3 + +# es printing, complex attributes + + Code + E(g)[[1]] + Output + + 1/3 edge (vertex names): + $color + [1] "red" + + $weight + [1] 10 + + $cmpx + $cmpx[[1]] + [1] 1 2 3 4 + + + Code + E(g)[[2:3]] + Output + + 2/3 edges (vertex names): + $color + [1] "red" "red" + + $weight + [1] 9 3 + + $cmpx + $cmpx[[1]] + [1] 1 2 3 4 + + $cmpx[[2]] + [1] 1 2 3 4 + + + diff --git a/tests/testthat/_snaps/vs-es-printing.md b/tests/testthat/_snaps/vs-es-printing.md deleted file mode 100644 index 966931090f8..00000000000 --- a/tests/testthat/_snaps/vs-es-printing.md +++ /dev/null @@ -1,119 +0,0 @@ -# vs printing - - Code - V(g)[[1]] - Output - + 1/3 vertex, named: - name color weight - 1 A red 10 - Code - V(g)[[2]] - Output - + 1/3 vertex, named: - name color weight - 2 B red 9 - Code - V(g)[1:2] - Output - + 2/3 vertices, named: - [1] A B - Code - V(g)[2:3] - Output - + 2/3 vertices, named: - [1] B C - -# vs printing, complex attributes - - Code - V(g)[[1]] - Output - + 1/3 vertex, named: - $name - [1] "A" - - $color - [1] "red" - - $weight - [1] 10 - - $cplx - $cplx[[1]] - [1] 1 2 3 4 - - - Code - V(g)[[2:3]] - Output - + 2/3 vertices, named: - $name - [1] "B" "C" - - $color - [1] "red" "red" - - $weight - [1] 9 3 - - $cplx - $cplx[[1]] - [1] 1 2 3 4 - - $cplx[[2]] - [1] 1 2 3 4 - - - -# es printing - - Code - E(g)[[1]] - Output - + 1/3 edge (vertex names): - tail head tid hid color weight - 1 A B 1 2 red 10 - Code - E(g)[[2:3]] - Output - + 2/3 edges (vertex names): - tail head tid hid color weight - 2 A C 1 3 red 9 - 3 B C 2 3 red 3 - -# es printing, complex attributes - - Code - E(g)[[1]] - Output - + 1/3 edge (vertex names): - $color - [1] "red" - - $weight - [1] 10 - - $cmpx - $cmpx[[1]] - [1] 1 2 3 4 - - - Code - E(g)[[2:3]] - Output - + 2/3 edges (vertex names): - $color - [1] "red" "red" - - $weight - [1] 9 3 - - $cmpx - $cmpx[[1]] - [1] 1 2 3 4 - - $cmpx[[2]] - [1] 1 2 3 4 - - - diff --git a/tests/testthat/test-bipartite.R b/tests/testthat/test-bipartite.R new file mode 100644 index 00000000000..1efe7ba3629 --- /dev/null +++ b/tests/testthat/test-bipartite.R @@ -0,0 +1,94 @@ +test_that("bipartite_projection works", { + local_rng_version("3.5.0") + withr::local_seed(42) + + g <- make_full_bipartite_graph(10, 5) + proj <- bipartite_projection(g) + expect_isomorphic(proj[[1]], make_full_graph(10)) + expect_isomorphic(proj[[2]], make_full_graph(5)) + + biadj_mat <- matrix(0, nrow = 5, ncol = 3) + rownames(biadj_mat) <- c("Alice", "Bob", "Cecil", "Dan", "Ethel") + colnames(biadj_mat) <- c("Party", "Skiing", "Badminton") + biadj_mat[] <- sample(0:1, length(biadj_mat), replace = TRUE) + biadj_mat + g2 <- graph_from_biadjacency_matrix(biadj_mat) + expect_equal(as.matrix(g2[1:5, 6:8]), biadj_mat) + expect_equal(as_unnamed_dense_matrix(g2[1:5, 1:5]), matrix(0, 5, 5)) + expect_equal(as_unnamed_dense_matrix(g2[6:8, 6:8]), matrix(0, 3, 3)) + + g2$name <- "Event network" + proj2 <- bipartite_projection(g2) + expect_equal( + as_unnamed_dense_matrix(proj2[[1]][]), + cbind(c(0, 2, 0, 2, 2), c(2, 0, 1, 2, 2), c(0, 1, 0, 0, 0), c(2, 2, 0, 0, 2), c(2, 2, 0, 2, 0)) + ) + expect_equal( + as_unnamed_dense_matrix(proj2[[2]][]), + cbind(c(0, 4, 1), c(4, 0, 1), c(1, 1, 0)) + ) + + bip_proj_size <- bipartite_projection_size(g2) + expect_equal(bip_proj_size$vcount1, vcount(proj2[[1]])) + expect_equal(bip_proj_size$ecount1, ecount(proj2[[1]])) + expect_equal(bip_proj_size$vcount2, vcount(proj2[[2]])) + expect_equal(bip_proj_size$ecount2, ecount(proj2[[2]])) +}) + +test_that("bipartite_projection can calculate only one projection", { + withr::local_seed(42) + + g <- sample_bipartite(5, 10, p = .3) + proj <- bipartite_projection(g) + proj_false <- bipartite_projection(g, which = "false") + proj_true <- bipartite_projection(g, which = "true") + + expect_isomorphic(proj$proj1, proj_false) + expect_isomorphic(proj$proj2, proj_true) + expect_equal(vertex.attributes(proj$proj1), vertex.attributes(proj_false)) + expect_equal(vertex.attributes(proj$proj2), vertex.attributes(proj_true)) + expect_equal(edge_attr(proj$proj1), edge_attr(proj_false)) + expect_equal(edge_attr(proj$proj2), edge_attr(proj_true)) +}) + +test_that("bipartite_projection removes 'type' attribute if requested", { + g <- make_full_bipartite_graph(10, 5) + proj <- bipartite_projection(g) + proj_false <- bipartite_projection(g, which = "true") + proj_true <- bipartite_projection(g, which = "false") + + proj_rmtype <- bipartite_projection(g, remove.type = FALSE) + proj_rm_false <- bipartite_projection(g, which = "true", remove.type = FALSE) + proj_rm_true <- bipartite_projection(g, which = "false", remove.type = FALSE) + + expect_false("type" %in% vertex_attr_names(proj[[1]])) + expect_false("type" %in% vertex_attr_names(proj[[2]])) + expect_false("type" %in% vertex_attr_names(proj_false)) + expect_false("type" %in% vertex_attr_names(proj_true)) + + expect_true("type" %in% vertex_attr_names(proj_rmtype[[1]])) + expect_true("type" %in% vertex_attr_names(proj_rmtype[[2]])) + expect_true("type" %in% vertex_attr_names(proj_rm_false)) + expect_true("type" %in% vertex_attr_names(proj_rm_true)) +}) + +test_that("bipartite_projection breaks for non-bipartite graphs (#543)", { + g <- graph_from_literal(A - 0, B - 1, A - 1, 0 - 1) + V(g)$type <- V(g)$name %in% LETTERS + + expect_error( + bipartite_projection_size(g), + "Non-bipartite edge found in bipartite projection" + ) + expect_error( + bipartite_projection(g), + "Non-bipartite edge found in bipartite projection" + ) +}) + +test_that("bipartite_projection prints a warning if the type attribute is non-logical (#476)", { + g <- make_full_bipartite_graph(10, 5) + V(g)$type <- as.numeric(V(g)$type) + expect_warning(bipartite_projection(g), "logical") + expect_warning(bipartite_projection_size(g), "logical") +}) diff --git a/tests/testthat/test-bipartite.projection.R b/tests/testthat/test-bipartite.projection.R deleted file mode 100644 index 24a82b879dc..00000000000 --- a/tests/testthat/test-bipartite.projection.R +++ /dev/null @@ -1,96 +0,0 @@ -test_that("bipartite_projection works", { - local_rng_version("3.5.0") - withr::local_seed(42) - - g <- make_full_bipartite_graph(10, 5) - proj <- bipartite_projection(g) - expect_isomorphic(proj[[1]], make_full_graph(10)) - expect_isomorphic(proj[[2]], make_full_graph(5)) - - M <- matrix(0, nrow = 5, ncol = 3) - rownames(M) <- c("Alice", "Bob", "Cecil", "Dan", "Ethel") - colnames(M) <- c("Party", "Skiing", "Badminton") - M[] <- sample(0:1, length(M), replace = TRUE) - M - g2 <- graph_from_biadjacency_matrix(M) - expect_equal(as.matrix(g2[1:5, 6:8]), M) - expect_equal(as.matrix(g2[1:5, 1:5]), matrix(0, 5, 5), ignore_attr = TRUE) - expect_equal(as.matrix(g2[6:8, 6:8]), matrix(0, 3, 3), ignore_attr = TRUE) - - g2$name <- "Event network" - proj2 <- bipartite_projection(g2) - expect_equal( - as.matrix(proj2[[1]][]), - cbind(c(0, 2, 0, 2, 2), c(2, 0, 1, 2, 2), c(0, 1, 0, 0, 0), c(2, 2, 0, 0, 2), c(2, 2, 0, 2, 0)), - ignore_attr = TRUE - ) - expect_equal( - as.matrix(proj2[[2]][]), - cbind(c(0, 4, 1), c(4, 0, 1), c(1, 1, 0)), - ignore_attr = TRUE - ) - - bs <- bipartite_projection_size(g2) - expect_equal(bs$vcount1, vcount(proj2[[1]])) - expect_equal(bs$ecount1, ecount(proj2[[1]])) - expect_equal(bs$vcount2, vcount(proj2[[2]])) - expect_equal(bs$ecount2, ecount(proj2[[2]])) -}) - -test_that("bipartite_projection can calculate only one projection", { - withr::local_seed(42) - - g <- sample_bipartite(5, 10, p = .3) - proj <- bipartite_projection(g) - proj1 <- bipartite_projection(g, which = "false") - proj2 <- bipartite_projection(g, which = "true") - - expect_isomorphic(proj$proj1, proj1) - expect_isomorphic(proj$proj2, proj2) - expect_equal(vertex.attributes(proj$proj1), vertex.attributes(proj1)) - expect_equal(vertex.attributes(proj$proj2), vertex.attributes(proj2)) - expect_equal(edge_attr(proj$proj1), edge_attr(proj1)) - expect_equal(edge_attr(proj$proj2), edge_attr(proj2)) -}) - -test_that("bipartite_projection removes 'type' attribute if requested", { - g <- make_full_bipartite_graph(10, 5) - proj <- bipartite_projection(g) - proj1 <- bipartite_projection(g, which = "true") - proj2 <- bipartite_projection(g, which = "false") - - proj3 <- bipartite_projection(g, remove.type = FALSE) - proj4 <- bipartite_projection(g, which = "true", remove.type = FALSE) - proj5 <- bipartite_projection(g, which = "false", remove.type = FALSE) - - expect_false("type" %in% vertex_attr_names(proj[[1]])) - expect_false("type" %in% vertex_attr_names(proj[[2]])) - expect_false("type" %in% vertex_attr_names(proj1)) - expect_false("type" %in% vertex_attr_names(proj2)) - - expect_true("type" %in% vertex_attr_names(proj3[[1]])) - expect_true("type" %in% vertex_attr_names(proj3[[2]])) - expect_true("type" %in% vertex_attr_names(proj4)) - expect_true("type" %in% vertex_attr_names(proj5)) -}) - -test_that("bipartite_projection breaks for non-bipartite graphs (#543)", { - g <- graph_from_literal(A - 0, B - 1, A - 1, 0 - 1) - V(g)$type <- V(g)$name %in% LETTERS - - expect_error( - bipartite_projection_size(g), - "Non-bipartite edge found in bipartite projection" - ) - expect_error( - bipartite_projection(g), - "Non-bipartite edge found in bipartite projection" - ) -}) - -test_that("bipartite_projection prints a warning if the type attribute is non-logical (#476)", { - g <- make_full_bipartite_graph(10, 5) - V(g)$type <- as.numeric(V(g)$type) - expect_warning(bipartite_projection(g), "logical") - expect_warning(bipartite_projection_size(g), "logical") -}) diff --git a/tests/testthat/test-cliques.R b/tests/testthat/test-cliques.R index 7abe7d05c02..363ec9d8b53 100644 --- a/tests/testthat/test-cliques.R +++ b/tests/testthat/test-cliques.R @@ -1,23 +1,23 @@ test_that("cliques() works", { withr::local_seed(42) - check.clique <- function(graph, vids) { + is_clique <- function(graph, vids) { s <- induced_subgraph(graph, vids) ecount(s) == vcount(s) * (vcount(s) - 1) / 2 } - g <- sample_gnp(100, 0.3) - expect_equal(clique_num(g), 6) + gnp <- sample_gnp(100, 0.3) + expect_equal(clique_num(gnp), 6) - cl <- sapply(cliques(g, min = 6), check.clique, graph = g) - lcl <- sapply(largest_cliques(g), check.clique, graph = g) + cl <- sapply(cliques(gnp, min = 6), is_clique, graph = gnp) + lcl <- sapply(largest_cliques(gnp), is_clique, graph = gnp) expect_equal(cl, lcl) expect_equal(cl, rep(TRUE, 17)) expect_equal(lcl, rep(TRUE, 17)) ## To have a bit less maximal cliques, about 100-200 usually - g <- sample_gnp(100, 0.03) - expect_true(all(sapply(max_cliques(g), check.clique, graph = g))) + gnp100 <- sample_gnp(100, 0.03) + expect_true(all(sapply(max_cliques(gnp100), is_clique, graph = gnp100))) }) test_that("clique_size_counts() works", { @@ -38,7 +38,7 @@ test_that("weighted_cliques works", { g <- make_graph(~ A - B - C - A - D - E - F - G - H - D - F - H - E - G - D) weights <- c(5, 5, 5, 3, 3, 3, 3, 2) - check.clique <- function(graph, vids, min_weight) { + is_clique_weight <- function(graph, vids, min_weight) { s <- induced_subgraph(graph, vids) ecount(s) == vcount(s) * (vcount(s) - 1) / 2 && sum(V(s)$weight) >= min_weight } @@ -49,27 +49,27 @@ test_that("weighted_cliques works", { ) V(g)$weight <- weights - cl <- sapply(weighted_cliques(g, min.weight = 9), check.clique, graph = g, min_weight = 9) + cl <- sapply(weighted_cliques(g, min.weight = 9), is_clique_weight, graph = g, min_weight = 9) expect_equal(cl, rep(TRUE, 14)) - g <- make_graph("zachary") - weights <- rep(1, vcount(g)) + karate <- make_graph("zachary") + weights <- rep(1, vcount(karate)) weights[c(1, 2, 3, 4, 14)] <- 3 - expect_equal(weighted_clique_num(g, vertex.weights = weights), 15) + expect_equal(weighted_clique_num(karate, vertex.weights = weights), 15) - V(g)$weight <- weights * 2 - expect_equal(weighted_clique_num(g), 30) + V(karate)$weight <- weights * 2 + expect_equal(weighted_clique_num(karate), 30) }) test_that("max_cliques() work", { withr::local_seed(42) - G <- sample_gnm(1000, 1000) - cli <- make_full_graph(10) + gnp <- sample_gnm(1000, 1000) + full10 <- make_full_graph(10) for (i in 1:10) { - G <- permute(G, sample(vcount(G))) - G <- G %u% cli + gnp <- permute(gnp, sample(vcount(gnp))) + gnp <- gnp %u% full10 } - G <- simplify(G) + gnp <- simplify(gnp) mysort <- function(x) { xl <- sapply(x, length) @@ -179,15 +179,15 @@ test_that("max_cliques() work", { lapply(res, as.integer) } - cl1 <- mysort(bk4(G, min = 3)) - cl2 <- mysort(unvs(max_cliques(G, min = 3))) + cl1 <- mysort(bk4(gnp, min = 3)) + cl2 <- mysort(unvs(max_cliques(gnp, min = 3))) expect_identical(cl1, cl2) }) test_that("max_cliques() work for subsets", { withr::local_seed(42) - G <- sample_gnp(100, .5) + gnp <- sample_gnp(100, .5) mysort <- function(x) { xl <- sapply(x, length) @@ -196,10 +196,10 @@ test_that("max_cliques() work for subsets", { x[order(xl, xc)] } - cl1 <- mysort(unvs(max_cliques(G, min = 8))) + cl1 <- mysort(unvs(max_cliques(gnp, min = 8))) - c1 <- unvs(max_cliques(G, min = 8, subset = 1:13)) - c2 <- unvs(max_cliques(G, min = 8, subset = 14:100)) + c1 <- unvs(max_cliques(gnp, min = 8, subset = 1:13)) + c2 <- unvs(max_cliques(gnp, min = 8, subset = 14:100)) cl2 <- mysort(c(c1, c2)) expect_identical(cl1, cl2) @@ -207,34 +207,34 @@ test_that("max_cliques() work for subsets", { test_that("count_max_cliques works", { withr::local_seed(42) - G <- sample_gnp(100, .5) + gnp <- sample_gnp(100, .5) - cl1 <- count_max_cliques(G, min = 8) + cl1 <- count_max_cliques(gnp, min = 8) - c1 <- count_max_cliques(G, min = 8, subset = 1:13) - c2 <- count_max_cliques(G, min = 8, subset = 14:100) + c1 <- count_max_cliques(gnp, min = 8, subset = 1:13) + c2 <- count_max_cliques(gnp, min = 8, subset = 14:100) cl2 <- c1 + c2 expect_identical(cl1, cl2) }) test_that("ivs() works", { - g <- sample_gnp(50, 0.8) - ivs <- ivs(g, min = ivs_size(g)) - ec <- sapply(seq_along(ivs), function(x) { - ecount(induced_subgraph(g, ivs[[x]])) + gnp <- sample_gnp(50, 0.8) + ivs <- ivs(gnp, min = ivs_size(gnp)) + edges_iv <- sapply(seq_along(ivs), function(x) { + ecount(induced_subgraph(gnp, ivs[[x]])) }) - expect_equal(unique(ec), 0) + expect_equal(unique(edges_iv), 0) }) test_that("ivs() works, cliques of complement", { # 2385298846 https://github.com/igraph/rigraph/pull/1541#issuecomment-2385298846 # that the independent vertex sets of G are # the same as the cliques of the complement of G (and vice versa) - g <- sample_gnp(50, 0.8) - ivs <- ivs(g, min = ivs_size(g)) %>% lapply(as.numeric) - complement <- complementer(g) - cliques <- cliques(complement, min = ivs_size(g)) %>% lapply(as.numeric) + gnp <- sample_gnp(50, 0.8) + ivs <- ivs(gnp, min = ivs_size(gnp)) %>% lapply(as.numeric) + complement <- complementer(gnp) + cliques <- cliques(complement, min = ivs_size(gnp)) %>% lapply(as.numeric) expect_equal(length(ivs), length(cliques)) @@ -276,5 +276,14 @@ test_that("largest_ivs() works", { }) expect_equal(unique(ec), 0) - ## TODO: check that they are largest + expect_length(ivs(g, min = length(livs[[1]]) + 1), 0) +}) + +test_that("largest_cliques works", { + g <- sample_gnp(50, 20 / 50) + lc <- largest_cliques(g) + expect_length(cliques(g, min = length(lc[[1]]) + 1), 0) + + lc_ring <- largest_cliques(make_ring(10)) + expect_equal(max(sapply(lc_ring, length)), 2) }) diff --git a/tests/testthat/test-community.R b/tests/testthat/test-community.R index cb570740b96..a2069b1a283 100644 --- a/tests/testthat/test-community.R +++ b/tests/testthat/test-community.R @@ -447,3 +447,36 @@ test_that("groups works", { expect_equal(gr, structure(list(`1` = letters[1:10], `2` = letters[11:15]), .Dim = 2L, .Dimnames = list(c("1", "2")))) }) + +test_that("voronoi works", { + res <- voronoi_cells(make_ring(10), c(1, 6)) + expect_equal(res$membership, c(0, 0, 0, 1, 1, 1, 1, 1, 0, 0)) + expect_equal(res$distances, c(0, 1, 2, 2, 1, 0, 1, 2, 2, 1)) +}) + +test_that("voronoi works with weights", { + res <- voronoi_cells(make_ring(10), c(1, 6), weights = 1:10) + expect_equal(res$membership, c(0, 0, 0, 0, 1, 1, 1, 1, 0, 0)) + expect_equal(res$distances, c(0, 1, 3, 6, 5, 0, 6, 13, 19, 10)) +}) + +test_that("contract works", { + local_rng_version("3.5.0") + withr::local_seed(42) + + g <- make_ring(10) + g$name <- "Ring" + V(g)$name <- letters[1:vcount(g)] + E(g)$weight <- sample(ecount(g)) + + g2 <- contract(g, rep(1:5, each = 2), + vertex.attr.comb = toString + ) + + expect_equal(g2$name, g$name) + expect_equal(V(g2)$name, c("a, b", "c, d", "e, f", "g, h", "i, j")) + expect_equal( + as_unnamed_dense_matrix(g2[]), + cbind(c(10, 9, 0, 0, 7), c(9, 3, 6, 0, 0), c(0, 6, 4, 8, 0), c(0, 0, 8, 5, 1), c(7, 0, 0, 1, 2)) + ) +}) diff --git a/tests/testthat/test-contract.vertices.R b/tests/testthat/test-contract.vertices.R index 3b2304522a7..e69de29bb2d 100644 --- a/tests/testthat/test-contract.vertices.R +++ b/tests/testthat/test-contract.vertices.R @@ -1,23 +0,0 @@ -test_that("contract works", { - local_rng_version("3.5.0") - withr::local_seed(42) - - g <- make_ring(10) - g$name <- "Ring" - V(g)$name <- letters[1:vcount(g)] - E(g)$weight <- sample(ecount(g)) - - g2 <- contract(g, rep(1:5, each = 2), - vertex.attr.comb = toString - ) - - ## graph and edge attributes are kept, vertex attributes are - ## combined using the 'toString' function. - expect_equal(g2$name, g$name) - expect_equal(V(g2)$name, c("a, b", "c, d", "e, f", "g, h", "i, j")) - expect_equal( - as.matrix(g2[]), - cbind(c(10, 9, 0, 0, 7), c(9, 3, 6, 0, 0), c(0, 6, 4, 8, 0), c(0, 0, 8, 5, 1), c(7, 0, 0, 1, 2)), - ignore_attr = TRUE - ) -}) diff --git a/tests/testthat/test-conversion.R b/tests/testthat/test-conversion.R index f127975035f..643c195f4cf 100644 --- a/tests/testthat/test-conversion.R +++ b/tests/testthat/test-conversion.R @@ -53,7 +53,7 @@ test_that("as.undirected() deprecation", { }) test_that("as_undirected() keeps attributes", { - g <- graph_from_literal(A +-+ B, A --+ C, C +-+ D) + g <- graph_from_literal(A + -+B, A - -+C, C + -+D) g$name <- "Tiny graph" E(g)$weight <- seq_len(ecount(g)) @@ -555,3 +555,44 @@ test_that("graph_from_data_frame works on matrices", { el2 <- as_data_frame(g) expect_equal(as.data.frame(el), el2, ignore_attr = TRUE) }) + +test_that("edge names work", { + ## named edges + local_igraph_options(print.edge.attributes = TRUE) + g <- make_ring(10) + E(g)$name <- letters[1:ecount(g)] + g2 <- delete_edges(g, c("b", "d", "e")) + expect_equal( + as_edgelist(g2), + structure(c(1, 3, 6, 7, 8, 9, 1, 2, 4, 7, 8, 9, 10, 10), .Dim = c(7L, 2L)) + ) + + ## named vertices + g <- make_ring(10) + V(g)$name <- letters[1:vcount(g)] + g3 <- delete_edges(g, c("a|b", "f|g", "c|b")) + expect_equal( + as_edgelist(g3), + structure(c("c", "d", "e", "g", "h", "i", "a", "d", "e", "f", "h", "i", "j", "j"), .Dim = c(7L, 2L)) + ) + + + ## no names at all, but select edges based on vertices + g <- make_ring(10) + g4 <- delete_edges(g, c("1|2", "8|7", "1|10")) + expect_equal( + as_edgelist(g4), + structure(c(2, 3, 4, 5, 6, 8, 9, 3, 4, 5, 6, 7, 9, 10), .Dim = c(7L, 2L)) + ) + + + ## mix edge names and vertex names + g <- make_ring(10) + V(g)$name <- letters[1:vcount(g)] + E(g)$name <- LETTERS[1:ecount(g)] + g5 <- delete_edges(g, c("a|b", "F", "j|i")) + expect_equal( + as_edgelist(g5), + structure(c("b", "c", "d", "e", "g", "h", "a", "c", "d", "e", "f", "h", "i", "j"), .Dim = c(7L, 2L)) + ) +}) diff --git a/tests/testthat/test-is.chordal.R b/tests/testthat/test-decomposition.R similarity index 100% rename from tests/testthat/test-is.chordal.R rename to tests/testthat/test-decomposition.R diff --git a/tests/testthat/test-dyad.census.R b/tests/testthat/test-dyad.census.R index 828a50764f4..e69de29bb2d 100644 --- a/tests/testthat/test-dyad.census.R +++ b/tests/testthat/test-dyad.census.R @@ -1,28 +0,0 @@ -test_that("dyad_census works", { - g1 <- make_ring(10) - expect_warning(dc1 <- dyad_census(g1), "directed") - expect_equal(dc1, list(mut = 10, asym = 0, null = 35)) - - g2 <- make_ring(10, directed = TRUE, mutual = TRUE) - dc2 <- dyad_census(g2) - expect_equal(dc2, list(mut = 10, asym = 0, null = 35)) - - g3 <- make_ring(10, directed = TRUE, mutual = FALSE) - dc3 <- dyad_census(g3) - expect_equal(dc3, list(mut = 0, asym = 10, null = 35)) - - # Supporting 64-bit integers now, can't test for overflow -}) - -test_that("dyad_census works with celegansneural", { - ce <- simplify(read_graph(gzfile("celegansneural.gml.gz"), format = "gml")) - dc <- dyad_census(ce) - - expect_equal(dc, list(mut = 197, asym = 1951, null = 41808)) - expect_equal(sum(which_mutual(ce)), dc$mut * 2) - expect_equal( - ecount(as_undirected(ce, mode = "collapse")) - dc$mut, - dc$asym - ) - expect_equal(sum(unlist(dc)), vcount(ce) * (vcount(ce) - 1) / 2) -}) diff --git a/tests/testthat/test-edgenames.R b/tests/testthat/test-edgenames.R deleted file mode 100644 index 587a2c03526..00000000000 --- a/tests/testthat/test-edgenames.R +++ /dev/null @@ -1,40 +0,0 @@ -test_that("edge names work", { - ## named edges - local_igraph_options(print.edge.attributes = TRUE) - g <- make_ring(10) - E(g)$name <- letters[1:ecount(g)] - g2 <- delete_edges(g, c("b", "d", "e")) - expect_equal( - as_edgelist(g2), - structure(c(1, 3, 6, 7, 8, 9, 1, 2, 4, 7, 8, 9, 10, 10), .Dim = c(7L, 2L)) - ) - - ## named vertices - g <- make_ring(10) - V(g)$name <- letters[1:vcount(g)] - g3 <- delete_edges(g, c("a|b", "f|g", "c|b")) - expect_equal( - as_edgelist(g3), - structure(c("c", "d", "e", "g", "h", "i", "a", "d", "e", "f", "h", "i", "j", "j"), .Dim = c(7L, 2L)) - ) - - - ## no names at all, but select edges based on vertices - g <- make_ring(10) - g4 <- delete_edges(g, c("1|2", "8|7", "1|10")) - expect_equal( - as_edgelist(g4), - structure(c(2, 3, 4, 5, 6, 8, 9, 3, 4, 5, 6, 7, 9, 10), .Dim = c(7L, 2L)) - ) - - - ## mix edge names and vertex names - g <- make_ring(10) - V(g)$name <- letters[1:vcount(g)] - E(g)$name <- LETTERS[1:ecount(g)] - g5 <- delete_edges(g, c("a|b", "F", "j|i")) - expect_equal( - as_edgelist(g5), - structure(c("b", "c", "d", "e", "g", "h", "a", "c", "d", "e", "f", "h", "i", "j"), .Dim = c(7L, 2L)) - ) -}) diff --git a/tests/testthat/test-flow.R b/tests/testthat/test-flow.R index 1f459cee750..45e6c797397 100644 --- a/tests/testthat/test-flow.R +++ b/tests/testthat/test-flow.R @@ -45,12 +45,12 @@ test_that("min_cut() errors work", { }) test_that("st_cuts() works", { - g_path <- graph_from_literal(a -+ b -+ c -+ d -+ e) + g_path <- graph_from_literal(a - +b - +c - +d - +e) all_cuts_path <- st_cuts(g_path, source = "a", target = "e") expect_equal(unvs(all_cuts_path$cuts), list(1, 2, 3, 4)) expect_equal(unvs(all_cuts_path$partition1s), list(1, 1:2, 1:3, 1:4)) - g_star_v7 <- graph_from_literal(s -+ a:b -+ t, a -+ 1:2:3 -+ b) + g_star_v7 <- graph_from_literal(s - +a:b - +t, a - +1:2:3 - +b) all_cuts_star_v7 <- st_cuts(g_star_v7, source = "s", target = "t") expect_equal( unvs(all_cuts_star_v7$cuts), @@ -69,7 +69,7 @@ test_that("st_cuts() works", { ) ) - g_star_v9 <- graph_from_literal(s -+ a:b -+ t, a -+ 1:2:3:4:5 -+ b) + g_star_v9 <- graph_from_literal(s - +a:b - +t, a - +1:2:3:4:5 - +b) all_cuts_star_v9 <- st_min_cuts(g_star_v9, source = "s", target = "t") expect_equal(all_cuts_star_v9$value, 2) expect_equal(unvs(all_cuts_star_v9$cuts), list(c(1, 2), c(1, 9), c(3, 9))) @@ -77,7 +77,7 @@ test_that("st_cuts() works", { }) test_that("st_cuts errors work", { - g_path <- graph_from_literal(a -+ b -+ c -+ d -+ e) + g_path <- graph_from_literal(a - +b - +c - +d - +e) expect_snapshot(st_cuts(g_path, source = "a", target = NULL), error = TRUE) expect_snapshot(st_cuts(g_path, source = NULL, target = "a"), error = TRUE) @@ -215,9 +215,9 @@ test_that("dominator_tree errors work", { test_that("dominator_tree works -- legacy", { g <- graph_from_literal( - R -+ A:B:C, A -+ D, B -+ A:D:E, C -+ F:G, D -+ L, - E -+ H, F -+ I, G -+ I:J, H -+ E:K, I -+ K, J -+ I, - K -+ I:R, L -+ H + R - +A:B:C, A - +D, B - +A:D:E, C - +F:G, D - +L, + E - +H, F - +I, G - +I:J, H - +E:K, I - +K, J - +I, + K - +I:R, L - +H ) dtree <- dominator_tree(g, root = "R") names <- c("$root", V(g)$name) @@ -250,7 +250,7 @@ test_that("min_st_separators() works for the note case", { test_that("Minimal s-t separators work", { # bug 1033045 - g <- graph_from_literal(a -- 1:3 -- 5 -- 2:4 -- b, 1 -- 2, 3 -- 4) + g <- graph_from_literal(a - -1:3 - -5 - -2:4 - -b, 1 - -2, 3 - -4) stsep <- min_st_separators(g) ims <- sapply(stsep, is_min_separator, graph = g) expect_equal(ims, rep(TRUE, 9)) @@ -275,3 +275,43 @@ test_that("min_separators works", { sep <- min_separators(camp) expect_true(all(sapply(sep, is_min_separator, graph = camp))) }) + +test_that("adhesion works", { + karate <- make_graph("Zachary") + expect_equal(adhesion(karate), 1) + expect_equal(cohesion(karate), 1) + + kite <- graph_from_literal( + Andre - Beverly:Carol:Diane:Fernando, + Beverly - Andre:Diane:Ed:Garth, + Carol - Andre:Diane:Fernando, + Diane - Andre:Beverly:Carol:Ed:Fernando:Garth, + Ed - Beverly:Diane:Garth, + Fernando - Andre:Carol:Diane:Garth:Heather, + Garth - Beverly:Diane:Ed:Fernando:Heather, + Heather - Fernando:Garth:Ike, + Ike - Heather:Jane, + Jane - Ike + ) + + expect_equal(adhesion(kite), 1) + expect_equal(cohesion(kite), 1) + + camp <- graph_from_literal( + Harry:Steve:Don:Bert - Harry:Steve:Don:Bert, + Pam:Brazey:Carol:Pat - Pam:Brazey:Carol:Pat, + Holly - Carol:Pat:Pam:Jennie:Bill, + Bill - Pauline:Michael:Lee:Holly, + Pauline - Bill:Jennie:Ann, + Jennie - Holly:Michael:Lee:Ann:Pauline, + Michael - Bill:Jennie:Ann:Lee:John, + Ann - Michael:Jennie:Pauline, + Lee - Michael:Bill:Jennie, + Gery - Pat:Steve:Russ:John, + Russ - Steve:Bert:Gery:John, + John - Gery:Russ:Michael + ) + + expect_equal(adhesion(camp), 2) + expect_equal(cohesion(camp), 2) +}) diff --git a/tests/testthat/test-graphlets.R b/tests/testthat/test-glet.R similarity index 85% rename from tests/testthat/test-graphlets.R rename to tests/testthat/test-glet.R index 3f14221bb3d..2f899c84742 100644 --- a/tests/testthat/test-graphlets.R +++ b/tests/testthat/test-glet.R @@ -5,39 +5,38 @@ sortgl <- function(x) { } test_that("Graphlets work for some simple graphs", { - g <- make_full_graph(5) - E(g)$weight <- 1 - gl <- graphlet_basis(g) + full <- make_full_graph(5) + E(full)$weight <- 1 + full_glet <- graphlet_basis(full) - expect_equal(names(gl), c("cliques", "thresholds")) - expect_equal(length(gl$cliques), 1) - expect_equal(sort(gl$cliques[[1]]), 1:vcount(g)) - expect_equal(gl$thresholds, 1) + expect_equal(names(full_glet), c("cliques", "thresholds")) + expect_equal(length(full_glet$cliques), 1) + expect_equal(sort(full_glet$cliques[[1]]), 1:vcount(full)) + expect_equal(full_glet$thresholds, 1) - g2 <- make_full_graph(5) - E(g2)$weight <- 1 - E(g2)[1 %--% 2]$weight <- 2 - gl2 <- sortgl(graphlet_basis(g2)) + E(full)[1 %--% 2]$weight <- 2 + full_glet2 <- sortgl(graphlet_basis(full)) - expect_equal(gl2, list(cliques = list(1:2, 1:5), thresholds = c(2, 1))) + expect_equal( + full_glet2, + list(cliques = list(1:2, 1:5), thresholds = c(2, 1)) + ) }) test_that("Graphlets filtering works", { - gt <- data.frame( + df <- data.frame( from = c("A", "A", "B", "B", "B", "C", "C", "D"), to = c("B", "C", "C", "D", "E", "D", "E", "E"), weight = c(8, 8, 8, 5, 5, 5, 5, 5) ) - g <- graph_from_data_frame(gt, directed = FALSE, vertices = data.frame(LETTERS[1:5])) - gl <- sortgl(graphlet_basis(g)) + g <- graph_from_data_frame(df, directed = FALSE, vertices = data.frame(LETTERS[1:5])) + glet <- sortgl(graphlet_basis(g)) - expect_equal(gl$cliques, list(1:3, 2:5)) - expect_equal(gl$thresholds, c(8, 5)) + expect_equal(glet$cliques, list(1:3, 2:5)) + expect_equal(glet$thresholds, c(8, 5)) }) -## Naive version of graphlets - threshold.net <- function(graph, level) { N <- vcount(graph) graph.t <- delete_edges(graph, which(E(graph)$weight < level)) diff --git a/tests/testthat/test-graph.adhesion.R b/tests/testthat/test-graph.adhesion.R deleted file mode 100644 index 3946002e4f5..00000000000 --- a/tests/testthat/test-graph.adhesion.R +++ /dev/null @@ -1,39 +0,0 @@ -test_that("adhesion works", { - g <- make_graph("Zachary") - expect_equal(adhesion(g), 1) - expect_equal(cohesion(g), 1) - - kite <- graph_from_literal( - Andre - Beverly:Carol:Diane:Fernando, - Beverly - Andre:Diane:Ed:Garth, - Carol - Andre:Diane:Fernando, - Diane - Andre:Beverly:Carol:Ed:Fernando:Garth, - Ed - Beverly:Diane:Garth, - Fernando - Andre:Carol:Diane:Garth:Heather, - Garth - Beverly:Diane:Ed:Fernando:Heather, - Heather - Fernando:Garth:Ike, - Ike - Heather:Jane, - Jane - Ike - ) - - expect_equal(adhesion(kite), 1) - expect_equal(cohesion(kite), 1) - - camp <- graph_from_literal( - Harry:Steve:Don:Bert - Harry:Steve:Don:Bert, - Pam:Brazey:Carol:Pat - Pam:Brazey:Carol:Pat, - Holly - Carol:Pat:Pam:Jennie:Bill, - Bill - Pauline:Michael:Lee:Holly, - Pauline - Bill:Jennie:Ann, - Jennie - Holly:Michael:Lee:Ann:Pauline, - Michael - Bill:Jennie:Ann:Lee:John, - Ann - Michael:Jennie:Pauline, - Lee - Michael:Bill:Jennie, - Gery - Pat:Steve:Russ:John, - Russ - Steve:Bert:Gery:John, - John - Gery:Russ:Michael - ) - - expect_equal(adhesion(camp), 2) - expect_equal(cohesion(camp), 2) -}) diff --git a/tests/testthat/test-igraph.options.R b/tests/testthat/test-igraph.options.R deleted file mode 100644 index 41fa43483e9..00000000000 --- a/tests/testthat/test-igraph.options.R +++ /dev/null @@ -1,39 +0,0 @@ -test_that("igraph_options works", { - old <- igraph_options(verbose = TRUE) - on.exit(igraph_options(old)) - expect_true(igraph_opt("verbose")) - - igraph_options(verbose = FALSE) - expect_false(igraph_opt("verbose")) -}) - -test_that("we can restore old options", { - old_1 <- igraph_opt("sparsematrices") - old_2 <- igraph_opt("annotate.plot") - - old <- igraph_options( - sparsematrices = FALSE, - annotate.plot = TRUE - ) - - expect_equal(igraph_opt("sparsematrices"), FALSE) - expect_equal(igraph_opt("annotate.plot"), TRUE) - - igraph_options(old) - - expect_equal(igraph_opt("sparsematrices"), old_1) - expect_equal(igraph_opt("annotate.plot"), old_2) -}) - -test_that("with_igraph_opt works", { - on.exit(try(igraph_options(old)), add = TRUE) - old <- igraph_options(sparsematrices = TRUE) - - res <- with_igraph_opt( - list(sparsematrices = FALSE), - make_ring(3)[] - ) - - expect_equal(igraph_opt("sparsematrices"), TRUE) - expect_true(inherits(res, "matrix")) -}) diff --git a/tests/testthat/test-largest.cliques.R b/tests/testthat/test-largest.cliques.R deleted file mode 100644 index aab8f4e563b..00000000000 --- a/tests/testthat/test-largest.cliques.R +++ /dev/null @@ -1,12 +0,0 @@ -test_that("largest_cliques works", { - g <- sample_gnp(50, 20 / 50) - lc <- largest_cliques(g) - - ## TODO: this only checks that these are cliques - expect_equal( - unique(sapply(lc, function(x) { - edge_density(induced_subgraph(g, x)) - })), - 1 - ) -}) diff --git a/tests/testthat/test-make.R b/tests/testthat/test-make.R index 70866217efc..ceb078d5539 100644 --- a/tests/testthat/test-make.R +++ b/tests/testthat/test-make.R @@ -61,8 +61,8 @@ test_that("error messages are proper", { test_that("we pass arguments unevaluated", { rlang::local_options(lifecycle_verbosity = "quiet") - g0 <- graph_from_literal(A -+ B:C) - g1 <- graph_(from_literal(A -+ B:C)) + g0 <- graph_from_literal(A - +B:C) + g1 <- graph_(from_literal(A - +B:C)) expect_identical_graphs(g0, g1) }) @@ -86,18 +86,18 @@ test_that("graph_from_literal() and undirected explosion", { test_that("graph_from_literal() and simple directed graphs", { local_igraph_options(print.id = FALSE) expect_snapshot({ - graph_from_literal(A -+ B) - graph_from_literal(A -+ B -+ C) - graph_from_literal(A -+ B -+ C -+ A) - graph_from_literal(A -+ B +- C -+ A) + graph_from_literal(A - +B) + graph_from_literal(A - +B - +C) + graph_from_literal(A - +B - +C - +A) + graph_from_literal(A - +B + -C - +A) }) }) test_that("graph_from_literal() and directed explosion", { local_igraph_options(print.id = FALSE) expect_snapshot({ - graph_from_literal(A:B:C -+ D:E, B:D +- C:E) - graph_from_literal(A:B:C -+ D:E +- F:G:H -+ I +- J:K:L:M) + graph_from_literal(A:B:C - +D:E, B:D + -C:E) + graph_from_literal(A:B:C - +D:E + -F:G:H - +I + -J:K:L:M) }) }) @@ -373,3 +373,33 @@ test_that("warnings are given for extra arguments in make_graph for notables", { expect_identical_graphs(Levi, Levi2) expect_identical_graphs(Levi, Levi3) }) + +test_that("graph is not updated if not in LHS", { + g <- make_( + ring(10), + with_vertex_(name = LETTERS[1:10]), + with_edge_(weight = 1:10) + ) + + vs <- V(g)[1:5] + vs$name <- letters[1:5] + expect_equal(V(g)$name, LETTERS[1:10]) + + es <- E(g) + es$weight <- 0 + expect_equal(E(g)$weight, 1:10) +}) + +test_that("graph is updated if in LHS", { + g <- make_( + ring(10), + with_vertex_(name = LETTERS[1:10]), + with_edge_(weight = 1:10) + ) + + V(g)[1:5]$name <- letters[1:5] + expect_equal(V(g)$name, c(letters[1:5], LETTERS[6:10])) + + E(g)[1:5]$weight <- 0 + expect_equal(E(g)$weight, c(rep(0, 5), 6:10)) +}) diff --git a/tests/testthat/test-motifs.R b/tests/testthat/test-motifs.R index f824308898a..dbdac0fe88b 100644 --- a/tests/testthat/test-motifs.R +++ b/tests/testthat/test-motifs.R @@ -1,43 +1,43 @@ -test_that("motif finding works", { +test_that("count_motifs works", { withr::local_seed(123) - b <- sample_gnp(10000, 4 / 10000, directed = TRUE) + gnp <- sample_gnp(10000, 4 / 10000, directed = TRUE) - mno <- count_motifs(b) + mno <- count_motifs(gnp) - mno0 <- count_motifs(b, cut.prob = c(1 / 3, 0, 0)) - mno1 <- count_motifs(b, cut.prob = c(0, 0, 1 / 3)) - mno2 <- count_motifs(b, cut.prob = c(0, 1 / 3, 0)) + mno0 <- count_motifs(gnp, cut.prob = c(1 / 3, 0, 0)) + mno1 <- count_motifs(gnp, cut.prob = c(0, 0, 1 / 3)) + mno2 <- count_motifs(gnp, cut.prob = c(0, 1 / 3, 0)) expect_equal( c(mno0 / mno, mno1 / mno, mno2 / mno), c(0.654821903845065, 0.666289144345659, 0.668393831285275) ) - mno3 <- count_motifs(b, cut.prob = c(0, 1 / 3, 1 / 3)) - mno4 <- count_motifs(b, cut.prob = c(1 / 3, 0, 1 / 3)) - mno5 <- count_motifs(b, cut.prob = c(1 / 3, 1 / 3, 0)) + mno3 <- count_motifs(gnp, cut.prob = c(0, 1 / 3, 1 / 3)) + mno4 <- count_motifs(gnp, cut.prob = c(1 / 3, 0, 1 / 3)) + mno5 <- count_motifs(gnp, cut.prob = c(1 / 3, 1 / 3, 0)) expect_equal( c(mno3 / mno, mno4 / mno, mno5 / mno), c(0.443959957465819, 0.441952797125797, 0.446004870037941) ) +}) - ###################### - +test_that("motifs works", { withr::local_seed(123) - b <- sample_gnp(10000, 4 / 10000, directed = TRUE) + gnp <- sample_gnp(10000, 4 / 10000, directed = TRUE) - m <- motifs(b) + m <- motifs(gnp) - m0 <- motifs(b, cut.prob = c(1 / 3, 0, 0)) - m1 <- motifs(b, cut.prob = c(0, 1 / 3, 0)) - m2 <- motifs(b, cut.prob = c(0, 0, 1 / 3)) + m0 <- motifs(gnp, cut.prob = c(1 / 3, 0, 0)) + m1 <- motifs(gnp, cut.prob = c(0, 1 / 3, 0)) + m2 <- motifs(gnp, cut.prob = c(0, 0, 1 / 3)) expect_equal(m0 / m, c(NA, NA, 0.653972107372707, NA, 0.653993015279859, 0.612244897959184, 0.657514670174019, 0.63013698630137, NaN, 0.538461538461538, NaN, 0.565217391304348, NaN, NaN, NaN, NaN)) expect_equal(m1 / m, c(NA, NA, 0.669562138856225, NA, 0.66808158454082, 0.73469387755102, 0.670819000404694, 0.657534246575342, NaN, 0.769230769230769, NaN, 0.739130434782609, NaN, NaN, NaN, NaN)) expect_equal(m2 / m, c(NA, NA, 0.666451718949538, NA, 0.665291458452201, 0.591836734693878, 0.666683528935654, 0.671232876712329, NaN, 0.753846153846154, NaN, 0.565217391304348, NaN, NaN, NaN, NaN)) - m3 <- motifs(b, cut.prob = c(0, 1 / 3, 1 / 3)) - m4 <- motifs(b, cut.prob = c(1 / 3, 1 / 3, 0)) - m5 <- motifs(b, cut.prob = c(1 / 3, 1 / 3, 0)) + m3 <- motifs(gnp, cut.prob = c(0, 1 / 3, 1 / 3)) + m4 <- motifs(gnp, cut.prob = c(1 / 3, 1 / 3, 0)) + m5 <- motifs(gnp, cut.prob = c(1 / 3, 1 / 3, 0)) expect_equal(m3 / m, c(NA, NA, 0.445611905574732, NA, 0.442789875290769, 0.448979591836735, 0.444695973290166, 0.424657534246575, NaN, 0.369230769230769, NaN, 0.608695652173913, NaN, NaN, NaN, NaN)) expect_equal(m4 / m, c(NA, NA, 0.439251981944392, NA, 0.439284975327761, 0.73469387755102, 0.445088021044112, 0.465753424657534, NaN, 0.630769230769231, NaN, 0.565217391304348, NaN, NaN, NaN, NaN)) @@ -60,3 +60,30 @@ test_that("sample_motifs works", { motif_count_all <- sample_motifs(g, sample = V(g)) expect_true(0 <= motif_count_all && motif_count_all <= n * (n - 1) * (n - 2) / 6) }) + +test_that("dyad_census works", { + g1 <- make_ring(10) + expect_warning(dc1 <- dyad_census(g1), "directed") + expect_equal(dc1, list(mut = 10, asym = 0, null = 35)) + + g2 <- make_ring(10, directed = TRUE, mutual = TRUE) + dc2 <- dyad_census(g2) + expect_equal(dc2, list(mut = 10, asym = 0, null = 35)) + + g3 <- make_ring(10, directed = TRUE, mutual = FALSE) + dc3 <- dyad_census(g3) + expect_equal(dc3, list(mut = 0, asym = 10, null = 35)) +}) + +test_that("dyad_census works with celegansneural", { + ce <- simplify(read_graph(gzfile("celegansneural.gml.gz"), format = "gml")) + dc <- dyad_census(ce) + + expect_equal(dc, list(mut = 197, asym = 1951, null = 41808)) + expect_equal(sum(which_mutual(ce)), dc$mut * 2) + expect_equal( + ecount(as_undirected(ce, mode = "collapse")) - dc$mut, + dc$asym + ) + expect_equal(sum(unlist(dc)), vcount(ce) * (vcount(ce) - 1) / 2) +}) diff --git a/tests/testthat/test-par.R b/tests/testthat/test-par.R index 6f65526e404..78da5045d07 100644 --- a/tests/testthat/test-par.R +++ b/tests/testthat/test-par.R @@ -16,3 +16,43 @@ test_that("print.id in snapshot (2)", { igraph_opt("print.id") }) }) + +test_that("igraph_options works", { + old <- igraph_options(verbose = TRUE) + on.exit(igraph_options(old)) + expect_true(igraph_opt("verbose")) + + igraph_options(verbose = FALSE) + expect_false(igraph_opt("verbose")) +}) + +test_that("we can restore old options", { + old_1 <- igraph_opt("sparsematrices") + old_2 <- igraph_opt("annotate.plot") + + old <- igraph_options( + sparsematrices = FALSE, + annotate.plot = TRUE + ) + + expect_equal(igraph_opt("sparsematrices"), FALSE) + expect_equal(igraph_opt("annotate.plot"), TRUE) + + igraph_options(old) + + expect_equal(igraph_opt("sparsematrices"), old_1) + expect_equal(igraph_opt("annotate.plot"), old_2) +}) + +test_that("with_igraph_opt works", { + on.exit(try(igraph_options(old)), add = TRUE) + old <- igraph_options(sparsematrices = TRUE) + + res <- with_igraph_opt( + list(sparsematrices = FALSE), + make_ring(3)[] + ) + + expect_equal(igraph_opt("sparsematrices"), TRUE) + expect_true(inherits(res, "matrix")) +}) diff --git a/tests/testthat/test-print.R b/tests/testthat/test-print.R index 1538669bfd3..1738a73ca49 100644 --- a/tests/testthat/test-print.R +++ b/tests/testthat/test-print.R @@ -64,3 +64,68 @@ test_that("print.igraph.es() uses vertex names", { E(g) }) }) + + +test_that("vs printing", { + local_igraph_options(print.id = FALSE) + + local_rng_version("3.5.0") + withr::local_seed(42) + g <- make_graph(~ A - A:B:C, B - A:B:C) %>% + set_vertex_attr("color", value = "red") %>% + set_vertex_attr("weight", value = sample(1:10, 3)) + + expect_snapshot({ + V(g)[[1]] + V(g)[[2]] + V(g)[1:2] + V(g)[2:3] + }) +}) + +test_that("vs printing, complex attributes", { + local_igraph_options(print.id = FALSE) + + local_rng_version("3.5.0") + withr::local_seed(42) + g <- make_graph(~ A - A:B:C, B - A:B:C) %>% + set_vertex_attr("color", value = "red") %>% + set_vertex_attr("weight", value = sample(1:10, 3)) %>% + set_vertex_attr("cplx", value = replicate(3, 1:4, simplify = FALSE)) + + expect_snapshot({ + V(g)[[1]] + V(g)[[2:3]] + }) +}) + +test_that("es printing", { + local_igraph_options(print.id = FALSE) + + local_rng_version("3.5.0") + withr::local_seed(42) + g <- make_graph(~ A - A:B:C, B - A:B:C) %>% + set_edge_attr("color", value = "red") %>% + set_edge_attr("weight", value = sample(1:10, 3)) + + expect_snapshot({ + E(g)[[1]] + E(g)[[2:3]] + }) +}) + +test_that("es printing, complex attributes", { + local_igraph_options(print.id = FALSE) + + local_rng_version("3.5.0") + withr::local_seed(42) + g <- make_graph(~ A - A:B:C, B - A:B:C) %>% + set_edge_attr("color", value = "red") %>% + set_edge_attr("weight", value = sample(1:10, 3)) %>% + set_edge_attr("cmpx", value = replicate(3, 1:4, simplify = FALSE)) + + expect_snapshot({ + E(g)[[1]] + E(g)[[2:3]] + }) +}) diff --git a/tests/testthat/test-sdf.R b/tests/testthat/test-sparsedf.R similarity index 100% rename from tests/testthat/test-sdf.R rename to tests/testthat/test-sparsedf.R diff --git a/tests/testthat/test-version.R b/tests/testthat/test-version.R deleted file mode 100644 index faaaba33b62..00000000000 --- a/tests/testthat/test-version.R +++ /dev/null @@ -1,15 +0,0 @@ -test_that("igraph_version returns a version string", { - ## This is essentially a semver regex, we do not allow a - ## leading 'v' and space after - regex <- paste0( - "\\b", # word boundary - "(?:0|[1-9][0-9]*)\\.", # major - "(?:0|[1-9][0-9]*)\\.", # minor - "(?:0|[1-9][0-9]*)", # patch - "(?:-[\\da-zA-Z\\-]+(?:\\.[\\da-zA-Z\\-]+)*)?", # prerelease - "(?:\\+[\\da-zA-Z\\-]+(?:\\.[\\da-zA-Z\\-]+)*)?", # word boundary - "\\b" - ) - - expect_true(grepl(regex, igraph_version())) -}) diff --git a/tests/testthat/test-versions.R b/tests/testthat/test-versions.R index 99ae2bcbbf0..ea1263b82d1 100644 --- a/tests/testthat/test-versions.R +++ b/tests/testthat/test-versions.R @@ -114,3 +114,19 @@ test_that("reading of old igraph formats", { s[["1.5.0"]] }) }) + +test_that("igraph_version returns a version string", { + ## This is essentially a semver regex, we do not allow a + ## leading 'v' and space after + regex <- paste0( + "\\b", # word boundary + "(?:0|[1-9][0-9]*)\\.", # major + "(?:0|[1-9][0-9]*)\\.", # minor + "(?:0|[1-9][0-9]*)", # patch + "(?:-[\\da-zA-Z\\-]+(?:\\.[\\da-zA-Z\\-]+)*)?", # prerelease + "(?:\\+[\\da-zA-Z\\-]+(?:\\.[\\da-zA-Z\\-]+)*)?", # word boundary + "\\b" + ) + + expect_true(grepl(regex, igraph_version())) +}) diff --git a/tests/testthat/test-voronoi.R b/tests/testthat/test-voronoi.R deleted file mode 100644 index 8d549e7e2e8..00000000000 --- a/tests/testthat/test-voronoi.R +++ /dev/null @@ -1,11 +0,0 @@ -test_that("voronoi works", { - res <- voronoi_cells(make_ring(10), c(1, 6)) - expect_equal(res$membership, c(0, 0, 0, 1, 1, 1, 1, 1, 0, 0)) - expect_equal(res$distances, c(0, 1, 2, 2, 1, 0, 1, 2, 2, 1)) -}) - -test_that("voronoi works with weights", { - res <- voronoi_cells(make_ring(10), c(1, 6), weights = 1:10) - expect_equal(res$membership, c(0, 0, 0, 0, 1, 1, 1, 1, 0, 0)) - expect_equal(res$distances, c(0, 1, 3, 6, 5, 0, 6, 13, 19, 10)) -}) diff --git a/tests/testthat/test-vs-es-printing.R b/tests/testthat/test-vs-es-printing.R deleted file mode 100644 index 2be58b371d0..00000000000 --- a/tests/testthat/test-vs-es-printing.R +++ /dev/null @@ -1,63 +0,0 @@ -test_that("vs printing", { - local_igraph_options(print.id = FALSE) - - local_rng_version("3.5.0") - withr::local_seed(42) - g <- make_graph(~ A - A:B:C, B - A:B:C) %>% - set_vertex_attr("color", value = "red") %>% - set_vertex_attr("weight", value = sample(1:10, 3)) - - expect_snapshot({ - V(g)[[1]] - V(g)[[2]] - V(g)[1:2] - V(g)[2:3] - }) -}) - -test_that("vs printing, complex attributes", { - local_igraph_options(print.id = FALSE) - - local_rng_version("3.5.0") - withr::local_seed(42) - g <- make_graph(~ A - A:B:C, B - A:B:C) %>% - set_vertex_attr("color", value = "red") %>% - set_vertex_attr("weight", value = sample(1:10, 3)) %>% - set_vertex_attr("cplx", value = replicate(3, 1:4, simplify = FALSE)) - - expect_snapshot({ - V(g)[[1]] - V(g)[[2:3]] - }) -}) - -test_that("es printing", { - local_igraph_options(print.id = FALSE) - - local_rng_version("3.5.0") - withr::local_seed(42) - g <- make_graph(~ A - A:B:C, B - A:B:C) %>% - set_edge_attr("color", value = "red") %>% - set_edge_attr("weight", value = sample(1:10, 3)) - - expect_snapshot({ - E(g)[[1]] - E(g)[[2:3]] - }) -}) - -test_that("es printing, complex attributes", { - local_igraph_options(print.id = FALSE) - - local_rng_version("3.5.0") - withr::local_seed(42) - g <- make_graph(~ A - A:B:C, B - A:B:C) %>% - set_edge_attr("color", value = "red") %>% - set_edge_attr("weight", value = sample(1:10, 3)) %>% - set_edge_attr("cmpx", value = replicate(3, 1:4, simplify = FALSE)) - - expect_snapshot({ - E(g)[[1]] - E(g)[[2:3]] - }) -}) diff --git a/tests/testthat/test-vs-es-quirks.R b/tests/testthat/test-vs-es-quirks.R deleted file mode 100644 index 6dffcbecccd..00000000000 --- a/tests/testthat/test-vs-es-quirks.R +++ /dev/null @@ -1,29 +0,0 @@ -test_that("graph is not updated if not in LHS", { - g <- make_( - ring(10), - with_vertex_(name = LETTERS[1:10]), - with_edge_(weight = 1:10) - ) - - vs <- V(g)[1:5] - vs$name <- letters[1:5] - expect_equal(V(g)$name, LETTERS[1:10]) - - es <- E(g) - es$weight <- 0 - expect_equal(E(g)$weight, 1:10) -}) - -test_that("graph is updated if in LHS", { - g <- make_( - ring(10), - with_vertex_(name = LETTERS[1:10]), - with_edge_(weight = 1:10) - ) - - V(g)[1:5]$name <- letters[1:5] - expect_equal(V(g)$name, c(letters[1:5], LETTERS[6:10])) - - E(g)[1:5]$weight <- 0 - expect_equal(E(g)$weight, c(rep(0, 5), 6:10)) -})