diff --git a/R/cohesive.blocks.R b/R/cohesive.blocks.R index e1c4f488a91..b27c2f859b3 100644 --- a/R/cohesive.blocks.R +++ b/R/cohesive.blocks.R @@ -224,6 +224,7 @@ blockGraphs <- function(blocks, graph) { #' For `graphs_from_cohesive_blocks()` and `export_pajek()` the same graph must be #' supplied whose cohesive block structure is given in the `blocks()` #' argument. +#' @inheritParams rlang::args_dots_empty #' @param labels Logical, whether to add the vertex labels to the result #' object. These labels can be then used when reporting and plotting the #' cohesive blocks. @@ -350,7 +351,33 @@ blockGraphs <- function(blocks, graph) { #' mark.border = 1, colbar = c(NA, NA, "cyan", "orange") #' ) #' -cohesive_blocks <- function(graph, labels = TRUE) { +cohesive_blocks <- function( + graph, + ..., + labels = TRUE +) { + # BEGIN GENERATED ARG_HANDLE: cohesive_blocks, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(labels = labels), + recover_new = c("labels"), + recover_old = c("labels"), + match_names = c("labels"), + match_to = c("labels"), + defaults = list(labels = TRUE), + head_args = c("graph"), + fn_name = "cohesive_blocks" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + # Argument checks ensure_igraph(graph) @@ -588,8 +615,37 @@ exportPajek.cohesiveblocks.nopf <- function(blocks, graph, file) { } #' @rdname cohesive_blocks +#' @inheritParams rlang::args_dots_empty #' @export -export_pajek <- function(blocks, graph, file, project.file = TRUE) { +export_pajek <- function( + blocks, + graph, + file, + ..., + project.file = TRUE +) { + # BEGIN GENERATED ARG_HANDLE: export_pajek, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(project.file = project.file), + recover_new = c("project.file"), + recover_old = c("project.file"), + match_names = c("project.file"), + match_to = c("project.file"), + defaults = list(project.file = TRUE), + head_args = c("blocks", "graph", "file"), + fn_name = "export_pajek" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + if (!project.file && (!is.character(file) || !nzchar(file))) { cli::cli_abort( "{.arg file} must be a filename (without extension) when writing diff --git a/R/cycles.R b/R/cycles.R index c3d65b5cae0..25356203038 100644 --- a/R/cycles.R +++ b/R/cycles.R @@ -31,6 +31,7 @@ #' a specific cycle. #' #' @param graph The input graph. +#' @inheritParams rlang::args_dots_empty #' @param mode Character constant specifying how to handle directed graphs. #' `out` follows edge directions, `in` follows edges in the reverse direction, #' and `all` ignores edge directions. Ignored in undirected graphs. diff --git a/R/flow.R b/R/flow.R index 79d6eb11161..ea2c4b6f509 100644 --- a/R/flow.R +++ b/R/flow.R @@ -343,6 +343,7 @@ dominator.tree <- function(graph, root, mode = c("out", "in", "all", "total")) { #' @param graph The input graph. #' @param source The ID of the source vertex. #' @param target The ID of the target vertex (sometimes also called sink). +#' @inheritParams rlang::args_dots_empty #' @param capacity Vector giving the capacity of the edges. If this is #' `NULL` (the default) then the `capacity` edge attribute is used. #' @param value.only Logical, if `TRUE` only the minimum cut value @@ -387,9 +388,32 @@ min_cut <- function( graph, source = NULL, target = NULL, + ..., capacity = NULL, value.only = TRUE ) { + # BEGIN GENERATED ARG_HANDLE: min_cut, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(capacity = capacity, value.only = value.only), + recover_new = c("capacity", "value.only"), + recover_old = c("capacity", "value.only"), + match_names = c("capacity", "value.only"), + match_to = c("capacity", "value.only"), + defaults = list(capacity = NULL, value.only = TRUE), + head_args = c("graph", "source", "target"), + fn_name = "min_cut" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + ensure_igraph(graph) if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { capacity <- E(graph)$capacity @@ -482,6 +506,7 @@ min_cut <- function( #' can be `NULL`, see details below. #' @param target The ID of the target vertex, for `vertex_connectivity()` it #' can be `NULL`, see details below. +#' @inheritParams rlang::args_dots_empty #' @param checks Logical. Whether to check that the graph is connected #' and also the degree of the vertices. If the graph is not (strongly) #' connected then the connectivity is obviously zero. Otherwise if the minimum @@ -518,8 +543,31 @@ vertex_connectivity <- function( graph, source = NULL, target = NULL, + ..., checks = TRUE ) { + # BEGIN GENERATED ARG_HANDLE: vertex_connectivity, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(checks = checks), + recover_new = c("checks"), + recover_old = c("checks"), + match_names = c("checks"), + match_to = c("checks"), + defaults = list(checks = TRUE), + head_args = c("graph", "source", "target"), + fn_name = "vertex_connectivity" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + ensure_igraph(graph) if (is.null(source) && is.null(target)) { @@ -589,6 +637,7 @@ vertex_connectivity <- function( #' can be `NULL`, see details below. #' @param target The ID of the target vertex, for `edge_connectivity()` it #' can be `NULL`, see details below. +#' @inheritParams rlang::args_dots_empty #' @param checks Logical. Whether to check that the graph is connected #' and also the degree of the vertices. If the graph is not (strongly) #' connected then the connectivity is obviously zero. Otherwise if the minimum @@ -621,8 +670,31 @@ edge_connectivity <- function( graph, source = NULL, target = NULL, + ..., checks = TRUE ) { + # BEGIN GENERATED ARG_HANDLE: edge_connectivity, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(checks = checks), + recover_new = c("checks"), + recover_old = c("checks"), + match_names = c("checks"), + match_to = c("checks"), + defaults = list(checks = TRUE), + head_args = c("graph", "source", "target"), + fn_name = "edge_connectivity" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + ensure_igraph(graph) if (is.null(source) && is.null(target)) { @@ -671,8 +743,35 @@ vertex_disjoint_paths <- function(graph, source = NULL, target = NULL) { } #' @rdname edge_connectivity +#' @inheritParams rlang::args_dots_empty #' @export -adhesion <- function(graph, checks = TRUE) { +adhesion <- function( + graph, + ..., + checks = TRUE +) { + # BEGIN GENERATED ARG_HANDLE: adhesion, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(checks = checks), + recover_new = c("checks"), + recover_old = c("checks"), + match_names = c("checks"), + match_to = c("checks"), + defaults = list(checks = TRUE), + head_args = c("graph"), + fn_name = "adhesion" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + adhesion_impl( graph = graph, checks = checks @@ -760,6 +859,7 @@ st_cuts <- function(graph, source, target) { #' @param graph The input graph. It must be directed. #' @param source The ID of the source vertex. #' @param target The ID of the target vertex. +#' @inheritParams rlang::args_dots_empty #' @param capacity Numeric vector giving the edge capacities. If this is #' `NULL` and the graph has a `weight` edge attribute, then this #' attribute defines the edge capacities. For forcing unit edge capacities, @@ -795,7 +895,35 @@ st_cuts <- function(graph, source, target) { #' st_min_cuts(g, source = "s", target = "t") #' @family flow #' @export -st_min_cuts <- function(graph, source, target, capacity = NULL) { +st_min_cuts <- function( + graph, + source, + target, + ..., + capacity = NULL +) { + # BEGIN GENERATED ARG_HANDLE: st_min_cuts, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(capacity = capacity), + recover_new = c("capacity"), + recover_old = c("capacity"), + match_names = c("capacity"), + match_to = c("capacity"), + defaults = list(capacity = NULL), + head_args = c("graph", "source", "target"), + fn_name = "st_min_cuts" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + all_st_mincuts_impl( graph = graph, source = source, @@ -829,6 +957,7 @@ st_min_cuts <- function(graph, source, target, capacity = NULL) { #' be collected and returned as part of the result. #' @param root The ID of the root (or source) vertex, this will be the root of #' the tree. +#' @inheritParams rlang::args_dots_empty #' @param mode Constant, must be \sQuote{`in`} or \sQuote{`out`}. If #' it is \sQuote{`in`}, then all directions are considered as opposite to #' the original one in the input graph. @@ -867,7 +996,34 @@ st_min_cuts <- function(graph, source, target, capacity = NULL) { #' plot(dtree$domtree, layout = layout, vertex.label = V(dtree$domtree)$name) #' @family flow #' @export -dominator_tree <- function(graph, root, mode = c("out", "in", "all", "total")) { +dominator_tree <- function( + graph, + root, + ..., + mode = c("out", "in", "all", "total") +) { + # BEGIN GENERATED ARG_HANDLE: dominator_tree, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(mode = mode), + recover_new = c("mode"), + recover_old = c("mode"), + match_names = c("mode"), + match_to = c("mode"), + defaults = list(mode = c("out", "in", "all", "total")), + head_args = c("graph", "root"), + fn_name = "dominator_tree" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + # Argument checks ensure_igraph(graph) @@ -968,6 +1124,7 @@ min_st_separators <- function(graph) { #' @param graph The input graph. #' @param source The ID of the source vertex. #' @param target The ID of the target vertex (sometimes also called sink). +#' @inheritParams rlang::args_dots_empty #' @param capacity Vector giving the capacity of the edges. If this is #' `NULL` (the default) then the `capacity` edge attribute is used. #' Note that the `weight` edge attribute is not used by this function. @@ -1014,7 +1171,35 @@ min_st_separators <- function(graph) { #' max_flow(g1, source = V(g1)["1"], target = V(g1)["2"]) #' @family flow #' @export -max_flow <- function(graph, source, target, capacity = NULL) { +max_flow <- function( + graph, + source, + target, + ..., + capacity = NULL +) { + # BEGIN GENERATED ARG_HANDLE: max_flow, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(capacity = capacity), + recover_new = c("capacity"), + recover_old = c("capacity"), + match_names = c("capacity"), + match_to = c("capacity"), + defaults = list(capacity = NULL), + head_args = c("graph", "source", "target"), + fn_name = "max_flow" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + maxflow_impl( graph = graph, source = source, diff --git a/man/cohesive_blocks.Rd b/man/cohesive_blocks.Rd index 6aa6f590330..4c80d62bd1e 100644 --- a/man/cohesive_blocks.Rd +++ b/man/cohesive_blocks.Rd @@ -17,7 +17,7 @@ \alias{max_cohesion} \title{Calculate Cohesive Blocks} \usage{ -cohesive_blocks(graph, labels = TRUE) +cohesive_blocks(graph, ..., labels = TRUE) \method{length}{cohesiveBlocks}(x) @@ -50,7 +50,7 @@ plot_hierarchy( ... ) -export_pajek(blocks, graph, file, project.file = TRUE) +export_pajek(blocks, graph, file, ..., project.file = TRUE) max_cohesion(blocks) } @@ -63,6 +63,9 @@ For \code{graphs_from_cohesive_blocks()} and \code{export_pajek()} the same grap supplied whose cohesive block structure is given in the \code{blocks()} argument.} +\item{\dots}{Additional arguments. \code{plot_hierarchy()} and \code{\link[=plot]{plot()}} pass +them to \code{plot.igraph()}. \code{\link[=print]{print()}} and \code{\link[=summary]{summary()}} ignore them.} + \item{labels}{Logical, whether to add the vertex labels to the result object. These labels can be then used when reporting and plotting the cohesive blocks.} @@ -70,9 +73,6 @@ cohesive blocks.} \item{blocks, x, object}{A \code{cohesiveBlocks} object, created with the \code{cohesive_blocks()} function.} -\item{\dots}{Additional arguments. \code{plot_hierarchy()} and \code{\link[=plot]{plot()}} pass -them to \code{plot.igraph()}. \code{\link[=print]{print()}} and \code{\link[=summary]{summary()}} ignore them.} - \item{y}{The graph whose cohesive blocks are supplied in the \code{x} argument.} diff --git a/man/dominator_tree.Rd b/man/dominator_tree.Rd index 4722cc5449d..b974e8c27aa 100644 --- a/man/dominator_tree.Rd +++ b/man/dominator_tree.Rd @@ -4,7 +4,7 @@ \alias{dominator_tree} \title{Dominator tree} \usage{ -dominator_tree(graph, root, mode = c("out", "in", "all", "total")) +dominator_tree(graph, root, ..., mode = c("out", "in", "all", "total")) } \arguments{ \item{graph}{A directed graph. If it is not a flowgraph, and it contains @@ -14,6 +14,8 @@ be collected and returned as part of the result.} \item{root}{The ID of the root (or source) vertex, this will be the root of the tree.} +\item{...}{These dots are for future extensions and must be empty.} + \item{mode}{Constant, must be \sQuote{\verb{in}} or \sQuote{\code{out}}. If it is \sQuote{\verb{in}}, then all directions are considered as opposite to the original one in the input graph.} diff --git a/man/edge_connectivity.Rd b/man/edge_connectivity.Rd index e4c31aa3669..d29daa1cb41 100644 --- a/man/edge_connectivity.Rd +++ b/man/edge_connectivity.Rd @@ -6,11 +6,11 @@ \alias{adhesion} \title{Edge connectivity} \usage{ -edge_connectivity(graph, source = NULL, target = NULL, checks = TRUE) +edge_connectivity(graph, source = NULL, target = NULL, ..., checks = TRUE) edge_disjoint_paths(graph, source = NULL, target = NULL) -adhesion(graph, checks = TRUE) +adhesion(graph, ..., checks = TRUE) } \arguments{ \item{graph}{The input graph.} @@ -21,6 +21,8 @@ can be \code{NULL}, see details below.} \item{target}{The ID of the target vertex, for \code{edge_connectivity()} it can be \code{NULL}, see details below.} +\item{...}{These dots are for future extensions and must be empty.} + \item{checks}{Logical. Whether to check that the graph is connected and also the degree of the vertices. If the graph is not (strongly) connected then the connectivity is obviously zero. Otherwise if the minimum diff --git a/man/max_flow.Rd b/man/max_flow.Rd index 47f9768161b..db5d0a1fbd8 100644 --- a/man/max_flow.Rd +++ b/man/max_flow.Rd @@ -4,7 +4,7 @@ \alias{max_flow} \title{Maximum flow in a graph} \usage{ -max_flow(graph, source, target, capacity = NULL) +max_flow(graph, source, target, ..., capacity = NULL) } \arguments{ \item{graph}{The input graph.} @@ -13,6 +13,8 @@ max_flow(graph, source, target, capacity = NULL) \item{target}{The ID of the target vertex (sometimes also called sink).} +\item{...}{These dots are for future extensions and must be empty.} + \item{capacity}{Vector giving the capacity of the edges. If this is \code{NULL} (the default) then the \code{capacity} edge attribute is used. Note that the \code{weight} edge attribute is not used by this function.} diff --git a/man/min_cut.Rd b/man/min_cut.Rd index 887c5354284..6cfd4826ab7 100644 --- a/man/min_cut.Rd +++ b/man/min_cut.Rd @@ -8,6 +8,7 @@ min_cut( graph, source = NULL, target = NULL, + ..., capacity = NULL, value.only = TRUE ) @@ -19,6 +20,8 @@ min_cut( \item{target}{The ID of the target vertex (sometimes also called sink).} +\item{...}{These dots are for future extensions and must be empty.} + \item{capacity}{Vector giving the capacity of the edges. If this is \code{NULL} (the default) then the \code{capacity} edge attribute is used.} diff --git a/man/st_min_cuts.Rd b/man/st_min_cuts.Rd index 073ea57f62f..9f0bbba1dcd 100644 --- a/man/st_min_cuts.Rd +++ b/man/st_min_cuts.Rd @@ -4,7 +4,7 @@ \alias{st_min_cuts} \title{List all minimum \eqn{(s,t)}-cuts of a graph} \usage{ -st_min_cuts(graph, source, target, capacity = NULL) +st_min_cuts(graph, source, target, ..., capacity = NULL) } \arguments{ \item{graph}{The input graph. It must be directed.} @@ -13,6 +13,8 @@ st_min_cuts(graph, source, target, capacity = NULL) \item{target}{The ID of the target vertex.} +\item{...}{These dots are for future extensions and must be empty.} + \item{capacity}{Numeric vector giving the edge capacities. If this is \code{NULL} and the graph has a \code{weight} edge attribute, then this attribute defines the edge capacities. For forcing unit edge capacities, diff --git a/man/vertex_connectivity.Rd b/man/vertex_connectivity.Rd index 35896753127..e6afe4da668 100644 --- a/man/vertex_connectivity.Rd +++ b/man/vertex_connectivity.Rd @@ -7,7 +7,7 @@ \alias{cohesion.igraph} \title{Vertex connectivity} \usage{ -vertex_connectivity(graph, source = NULL, target = NULL, checks = TRUE) +vertex_connectivity(graph, source = NULL, target = NULL, ..., checks = TRUE) vertex_disjoint_paths(graph, source = NULL, target = NULL) @@ -22,6 +22,9 @@ can be \code{NULL}, see details below.} \item{target}{The ID of the target vertex, for \code{vertex_connectivity()} it can be \code{NULL}, see details below.} +\item{...}{Additional arguments passed to methods. Not used by \code{vertex_connectivity()} +directly but may be used by other methods that implement \code{cohesion()}.} + \item{checks}{Logical. Whether to check that the graph is connected and also the degree of the vertices. If the graph is not (strongly) connected then the connectivity is obviously zero. Otherwise if the minimum @@ -29,9 +32,6 @@ degree is one then the vertex connectivity is also one. It is a good idea to perform these checks, as they can be done quickly compared to the connectivity calculation itself. They were suggested by Peter McMahan, thanks Peter.} - -\item{...}{Additional arguments passed to methods. Not used by \code{vertex_connectivity()} -directly but may be used by other methods that implement \code{cohesion()}.} } \value{ A scalar real value. diff --git a/tests/testthat/test-cohesive.blocks.R b/tests/testthat/test-cohesive.blocks.R new file mode 100644 index 00000000000..2780d37c299 --- /dev/null +++ b/tests/testthat/test-cohesive.blocks.R @@ -0,0 +1,52 @@ +# ---- ellipsis migration: argument coverage ---------------------------- + +test_that("cohesive_blocks() tail arguments and legacy positional recovery", { + # A triangle with a pendant vertex: the triangle is the only deeper block. + g <- graph_from_literal(A - B - C - A, C - D) + + # labels = FALSE must not copy the vertex names into the result. + res <- cohesive_blocks(g, labels = FALSE) + expect_s3_class(res, "cohesiveBlocks") + expect_null(res$labels) + expect_equal(unvs(blocks(res)), list(1:4, 1:3)) + expect_equal(cohesion(res), c(1, 2)) + + # The default copies the vertex names. + expect_identical(cohesive_blocks(g)$labels, c("A", "B", "C", "D")) + + lifecycle::expect_deprecated(res2 <- cohesive_blocks(g, FALSE)) + ref <- cohesive_blocks(g, labels = FALSE) + expect_null(res2$labels) + expect_equal(unvs(blocks(res2)), unvs(blocks(ref))) + expect_identical(cohesion(res2), cohesion(ref)) + expect_identical_graphs(hierarchy(res2), hierarchy(ref)) +}) + +test_that("export_pajek() tail arguments and legacy positional recovery", { + g <- graph_from_literal(A - B - C - A, C - D) + blks <- cohesive_blocks(g) + tmp <- withr::local_tempdir() + + # project.file = FALSE writes separate network, hierarchy and block files. + base <- file.path(tmp, "cb") + expect_null(export_pajek(blks, g, file = base, project.file = FALSE)) + expect_true(file.exists(paste0(base, ".net"))) + expect_true(file.exists(paste0(base, "_hierarchy.net"))) + expect_true(all(file.exists(paste0(base, "_block_", 1:2, ".clu")))) + + # The default writes a single Pajek project file. + pf <- file.path(tmp, "cb.paj") + export_pajek(blks, g, file = pf) + expect_identical( + readLines(pf, warn = FALSE)[1], + "*Network cohesive_blocks_input.net" + ) + + base2 <- file.path(tmp, "cb2") + lifecycle::expect_deprecated(res <- export_pajek(blks, g, base2, FALSE)) + expect_null(res) + expect_identical( + readLines(paste0(base2, ".net")), + readLines(paste0(base, ".net")) + ) +}) diff --git a/tests/testthat/test-flow.R b/tests/testthat/test-flow.R index 0370c238d4f..35f4f948805 100644 --- a/tests/testthat/test-flow.R +++ b/tests/testthat/test-flow.R @@ -360,3 +360,100 @@ test_that("adhesion works", { expect_equal(adhesion(camp), 2) expect_equal(cohesion(camp), 2) }) + +# ---- ellipsis migration: argument coverage ---------------------------- + +test_that("min_cut() tail arguments and legacy positional recovery", { + g <- make_graph(c(1, 2, 2, 3, 3, 4, 1, 6, 6, 5, 5, 4, 4, 1)) + cap <- c(3, 1, 2, 10, 1, 3, 2) + + # The capacity argument is used directly, no capacity edge attribute needed. + res <- min_cut(g, source = 1, target = 4, capacity = cap, value.only = FALSE) + expect_equal(res$value, 2) + expect_equal(as.vector(res$cut), c(2, 5)) + + lifecycle::expect_deprecated(res2 <- min_cut(g, 1, 4, cap, FALSE)) + expect_equal( + res2, + min_cut(g, source = 1, target = 4, capacity = cap, value.only = FALSE) + ) +}) + +test_that("max_flow() tail arguments and legacy positional recovery", { + g <- make_graph(c(1, 2, 2, 3), directed = TRUE) + + # The first explicit capacity is the bottleneck of the single path. + res <- max_flow(g, source = 1, target = 3, capacity = c(2, 5)) + expect_equal(res$value, 2) + expect_equal(as.vector(res$flow), c(2, 2)) + + lifecycle::expect_deprecated(res2 <- max_flow(g, 1, 3, c(2, 5))) + expect_equal(res2, max_flow(g, source = 1, target = 3, capacity = c(2, 5))) +}) + +test_that("st_min_cuts() tail arguments and legacy positional recovery", { + g <- graph_from_literal(a -+ b -+ c) + + # With these capacities only the cheaper second edge is a minimum cut. + res <- st_min_cuts(g, source = "a", target = "c", capacity = c(2, 1)) + expect_equal(res$value, 1) + expect_equal(unvs(res$cuts), list(2)) + + lifecycle::expect_deprecated(res2 <- st_min_cuts(g, "a", "c", c(2, 1))) + expect_equal( + res2, + st_min_cuts(g, source = "a", target = "c", capacity = c(2, 1)) + ) +}) + +test_that("vertex_connectivity() tail arguments and legacy positional recovery", { + g <- make_ring(5) + + # Disabling the quick degree checks must not change the result. + expect_equal(vertex_connectivity(g, checks = FALSE), 2) + + lifecycle::expect_deprecated( + res <- vertex_connectivity(g, NULL, NULL, FALSE) + ) + expect_identical(res, vertex_connectivity(g, checks = FALSE)) +}) + +test_that("edge_connectivity() tail arguments and legacy positional recovery", { + g <- make_ring(5) + + # Disabling the quick degree checks must not change the result. + expect_equal(edge_connectivity(g, checks = FALSE), 2) + + lifecycle::expect_deprecated( + res <- edge_connectivity(g, NULL, NULL, FALSE) + ) + expect_identical(res, edge_connectivity(g, checks = FALSE)) +}) + +test_that("adhesion() tail arguments and legacy positional recovery", { + g <- make_full_graph(5) + + # Disabling the quick degree checks must not change the result. + expect_equal(adhesion(g, checks = FALSE), 4) + + lifecycle::expect_deprecated(res <- adhesion(g, FALSE)) + expect_identical(res, adhesion(g, checks = FALSE)) +}) + +test_that("dominator_tree() tail arguments and legacy positional recovery", { + # A directed path 1 -> 2 -> 3 -> 4. + g <- make_ring(4, directed = TRUE, circular = FALSE) + + # mode = "in" reverses all edge directions, so vertex 4 dominates the path. + res <- dominator_tree(g, root = 4, mode = "in") + expect_equal(res$dom, c(2, 3, 4, -1)) + expect_length(res$leftout, 0) + + # The default mode = "out" follows the original directions from vertex 1. + expect_equal(dominator_tree(g, root = 1)$dom, c(-1, 1, 2, 3)) + + lifecycle::expect_deprecated(res2 <- dominator_tree(g, 4, "in")) + ref <- dominator_tree(g, root = 4, mode = "in") + expect_identical(res2$dom, ref$dom) + expect_identical_graphs(res2$domtree, ref$domtree) +}) diff --git a/tools/migrations/flow.R b/tools/migrations/flow.R new file mode 100644 index 00000000000..fbd47299fe5 --- /dev/null +++ b/tools/migrations/flow.R @@ -0,0 +1,109 @@ +# Argument-signature migrations: flow +# Schema: see tools/migrations/README.md. Regenerate with: +# Rscript tools/generate-migrations.R + +migrations <- list( + cohesive_blocks = list( + old = function(graph, labels) {}, + new = function( + graph, + ..., + labels = TRUE + ) {}, + when = "3.0.0" + ), + + export_pajek = list( + old = function(blocks, graph, file, project.file) {}, + new = function( + blocks, + graph, + file, + ..., + project.file = TRUE + ) {}, + when = "3.0.0" + ), + + adhesion = list( + old = function(graph, checks) {}, + new = function( + graph, + ..., + checks = TRUE + ) {}, + when = "3.0.0" + ), + + dominator_tree = list( + old = function(graph, root, mode) {}, + new = function( + graph, + root, + ..., + mode = c("out", "in", "all", "total") + ) {}, + when = "3.0.0" + ), + + edge_connectivity = list( + old = function(graph, source, target, checks) {}, + new = function( + graph, + source = NULL, + target = NULL, + ..., + checks = TRUE + ) {}, + when = "3.0.0" + ), + + max_flow = list( + old = function(graph, source, target, capacity) {}, + new = function( + graph, + source, + target, + ..., + capacity = NULL + ) {}, + when = "3.0.0" + ), + + min_cut = list( + old = function(graph, source, target, capacity, value.only) {}, + new = function( + graph, + source = NULL, + target = NULL, + ..., + capacity = NULL, + value.only = TRUE + ) {}, + when = "3.0.0" + ), + + st_min_cuts = list( + old = function(graph, source, target, capacity) {}, + new = function( + graph, + source, + target, + ..., + capacity = NULL + ) {}, + when = "3.0.0" + ), + + vertex_connectivity = list( + old = function(graph, source, target, checks) {}, + new = function( + graph, + source = NULL, + target = NULL, + ..., + checks = TRUE + ) {}, + when = "3.0.0" + ) +)