Nothing
describe("resolve_canonical_urls()", {
it("resolves canonical chains and leaves unmapped URLs unchanged", {
canonicals <- data.frame(
from = c("A", "B"),
to = c("B", "C")
)
result <- resolve_canonical_urls(c("A", "B", "X", NA), canonicals)
expect_identical(result$original, c("A", "B", "X", NA))
expect_identical(result$resolved, c("C", "C", "X", NA))
expect_identical(result$changed, c(TRUE, TRUE, FALSE, FALSE))
expect_identical(result$signal, c("canonical", "canonical", NA, NA))
})
it("treats self-canonicals as no-ops", {
canonicals <- data.frame(
from = c("A", "B"),
to = c("A", "C")
)
result <- resolve_canonical_urls(c("A", "B"), canonicals)
expect_identical(result$resolved, c("A", "C"))
expect_identical(result$changed, c(FALSE, TRUE))
})
it("uses canonical duplicate and loop policies from build_fold_map", {
duplicates <- data.frame(
from = c("A", "A"),
to = c("B", "C")
)
loop <- data.frame(
from = c("A", "B"),
to = c("B", "A")
)
expect_error(resolve_canonical_urls("A", duplicates), "Ambiguous")
first <- resolve_canonical_urls(
"A",
duplicates,
canonical_duplicate_from_policy = "first_wins"
)
expect_identical(first$resolved, "B")
expect_error(resolve_canonical_urls("A", loop), "cycle")
pruned <- resolve_canonical_urls(
"A",
loop,
canonical_loop_handling = "prune_loop"
)
expect_identical(pruned$resolved, "A")
expect_false(pruned$changed)
})
it("supports custom canonical column names", {
canonicals <- data.frame(
declared = c("A", "B"),
canonical = c("B", "C")
)
result <- resolve_canonical_urls(
"A",
canonicals,
canonical_from_col = "declared",
canonical_to_col = "canonical"
)
expect_identical(result$resolved, "C")
})
it("errors when urls is not a character vector", {
canonicals <- data.frame(from = "A", to = "B")
expect_error(
resolve_canonical_urls(123, canonicals),
"`urls` must be a character vector."
)
})
it("errors when canonicals_df is not a data frame", {
expect_error(
resolve_canonical_urls("A", "not a data frame"),
"`canonicals_df` must be a data frame."
)
})
it("errors when canonicals_df is missing required columns", {
canonicals <- data.frame(foo = "A", bar = "B")
expect_error(
resolve_canonical_urls("A", canonicals),
"`canonicals_df` must have 'from' and 'to' columns."
)
})
})
describe("resolve_canonicals()", {
it("folds edge endpoints through canonical declarations", {
edges <- data.frame(
from = c("A", "X"),
to = c("B", "Y"),
weight = c(1, 2)
)
canonicals <- data.frame(
from = c("A", "B"),
to = c("C", "D")
)
result <- resolve_canonicals(edges, canonicals)
expect_identical(result$from, c("C", "X"))
expect_identical(result$to, c("D", "Y"))
expect_identical(result$weight, c(1, 2))
expect_identical(
attr(result, "fold_map")$signal,
c("canonical", "canonical")
)
})
it("supports custom edge and canonical columns", {
edges <- data.frame(
source_url = "A",
target_url = "B"
)
canonicals <- data.frame(
declared = "B",
canonical = "C"
)
result <- resolve_canonicals(
edges,
canonicals,
edge_from_col = "source_url",
edge_to_col = "target_url",
canonical_from_col = "declared",
canonical_to_col = "canonical"
)
expect_identical(result$source_url, "A")
expect_identical(result$target_url, "C")
})
it("returns the edge list unchanged when the fold map is empty", {
edges <- data.frame(
from = c("A", "X"),
to = c("B", "Y")
)
canonicals <- data.frame(from = character(0), to = character(0))
result <- resolve_canonicals(edges, canonicals)
expect_identical(result$from, edges$from)
expect_identical(result$to, edges$to)
})
it("errors when edge_list_df is not a data frame", {
canonicals <- data.frame(from = "A", to = "B")
expect_error(
resolve_canonicals("not a data frame", canonicals),
"`edge_list_df` must be a data frame."
)
})
it("errors when edge_list_df is missing required columns", {
edges <- data.frame(x = "A", y = "B")
canonicals <- data.frame(from = "A", to = "B")
expect_error(
resolve_canonicals(edges, canonicals),
"`edge_list_df` must have 'from' and 'to' columns if not empty."
)
})
})
describe("resolve_folded_urls()", {
it("resolves mixed canonical and redirect chains", {
redirects <- data.frame(from = "B", to = "C")
canonicals <- data.frame(from = "A", to = "B")
result <- resolve_folded_urls(c("A", "B", "X"), redirects, canonicals)
expect_identical(result$resolved, c("C", "C", "X"))
expect_identical(result$changed, c(TRUE, TRUE, FALSE))
expect_identical(result$signal, c("canonical", "redirect", NA))
})
it("matches applying build_fold_map manually", {
redirects <- data.frame(
from = c("B", "D"),
to = c("C", "E")
)
canonicals <- data.frame(
from = c("A", "X"),
to = c("B", "D")
)
urls <- c("A", "B", "X", "Z")
result <- resolve_folded_urls(urls, redirects, canonicals)
expect_identical(result$resolved, c("C", "C", "E", "Z"))
expect_identical(
attr(result, "fold_map"),
build_fold_map(redirects, canonicals)
)
})
it("uses canonical_conflict_policy for same-source conflicts", {
redirects <- data.frame(from = "A", to = "B")
canonicals <- data.frame(from = "A", to = "D")
redirect_wins <- resolve_folded_urls("A", redirects, canonicals)
expect_identical(redirect_wins$resolved, "B")
expect_identical(redirect_wins$signal, "redirect")
expect_true(attr(redirect_wins, "conflicts")$disagrees)
expect_identical(
attr(redirect_wins, "ignored_canonicals")$canonical_to,
"D"
)
canonical_wins <- resolve_folded_urls(
"A",
redirects,
canonicals,
canonical_conflict_policy = "canonical_wins"
)
expect_identical(canonical_wins$resolved, "D")
expect_identical(canonical_wins$signal, "canonical")
expect_error(
resolve_folded_urls(
"A",
redirects,
canonicals,
canonical_conflict_policy = "error"
),
"conflict"
)
})
it("supports custom redirect and canonical columns", {
redirects <- data.frame(
old = "B",
new = "C"
)
canonicals <- data.frame(
declared = "A",
canonical = "B"
)
result <- resolve_folded_urls(
"A",
redirects,
canonicals,
redirect_from_col = "old",
redirect_to_col = "new",
canonical_from_col = "declared",
canonical_to_col = "canonical"
)
expect_identical(result$resolved, "C")
})
it("returns unchanged URLs when no signals are supplied", {
result <- resolve_folded_urls(c("A", NA), NULL, NULL)
expect_identical(result$resolved, c("A", NA))
expect_identical(result$changed, c(FALSE, FALSE))
expect_identical(result$signal, c(NA_character_, NA_character_))
expect_equal(nrow(attr(result, "fold_map")), 0L)
})
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.