Nothing
testthat::test_that("constructor sorts by key and preserves stable duplicate order", {
xs <- as_ordered_sequence(
list("bbb", "a", "cc", "dd", "e"),
keys = c(3, 1, 2, 2, 1)
)
testthat::expect_s3_class(xs, "ordered_sequence")
testthat::expect_equal(as.list(xs), list("a", "e", "cc", "dd", "bbb"))
testthat::expect_identical(length(xs), 5L)
})
testthat::test_that("min_key/max_key expose key extrema", {
xs <- as_ordered_sequence(list("bbb", "a", "cc"), keys = c(3, 1, 2))
testthat::expect_identical(min_key(xs), 1)
testthat::expect_identical(max_key(xs), 3)
empty <- ordered_sequence()
testthat::expect_null(min_key(empty))
testthat::expect_null(max_key(empty))
})
testthat::test_that("insert appends at right edge of equal-key block (FIFO ties)", {
xs <- as_ordered_sequence(list("bb", "aa", "c"), keys = c(2, 2, 1))
xs2 <- insert(xs, "dd", key = 2)
testthat::expect_equal(as.list(xs2), list("c", "bb", "aa", "dd"))
testthat::expect_equal(peek_key(xs2, 2), "bb")
out1 <- pop_key(xs2, 2)
out2 <- pop_key(out1$remaining, 2)
testthat::expect_equal(out1$value, "bb")
testthat::expect_equal(out2$value, "aa")
})
testthat::test_that("insert works on R backend when insertion is at right boundary", {
old_cpp <- getOption("immutables.use_cpp")
options(immutables.use_cpp = FALSE)
on.exit({
if(is.null(old_cpp)) {
options(immutables.use_cpp = NULL)
} else {
options(immutables.use_cpp = old_cpp)
}
}, add = TRUE)
xs <- as_ordered_sequence(list("a", "b"), keys = c(1, 2))
ys <- insert(xs, "c", key = 3)
testthat::expect_s3_class(ys, "ordered_sequence")
testthat::expect_equal(as.list(ys), list("a", "b", "c"))
})
testthat::test_that("insert preserves name state for named ordered_sequence", {
xs_num <- as_ordered_sequence(
setNames(as.list(c("a", "b")), c("ka", "kb")),
keys = c(1, 2)
)
v_num <- "c"
names(v_num) <- "kc"
ys_num <- insert(xs_num, v_num, key = 2)
testthat::expect_identical(unname(ys_num[["kc"]]), "c")
testthat::expect_identical(attr(ys_num, "measures")$.named_count, as.integer(length(ys_num)))
testthat::expect_true(validate_name_state(ys_num))
xs_date <- as_ordered_sequence(
setNames(as.list(c("a", "b")), c("da", "db")),
keys = as.Date(c("2024-01-01", "2024-01-03"))
)
v_date <- "c"
names(v_date) <- "dc"
ys_date <- insert(xs_date, v_date, key = as.Date("2024-01-02"))
testthat::expect_identical(unname(ys_date[["dc"]]), "c")
testthat::expect_identical(attr(ys_date, "measures")$.named_count, as.integer(length(ys_date)))
testthat::expect_true(validate_name_state(ys_date))
})
testthat::test_that("insert enforces named/unnamed consistency for ordered_sequence", {
named <- as_ordered_sequence(
setNames(as.list(c("a", "b")), c("ka", "kb")),
keys = c(1, 2)
)
testthat::expect_error(
insert(named, "c", key = 3),
"mixed named and unnamed"
)
unnamed <- as_ordered_sequence(list("a", "b"), keys = c(1, 2))
v_named <- "c"
names(v_named) <- "kc"
testthat::expect_error(
insert(unnamed, v_named, key = 3),
"mixed named and unnamed"
)
})
testthat::test_that("lower_bound and upper_bound behave at boundaries", {
xs <- as_ordered_sequence(list("bbb", "a", "cc", "dddd"), keys = c(3, 1, 2, 4))
lb1 <- lower_bound(xs, 2)
ub1 <- upper_bound(xs, 2)
lb9 <- lower_bound(xs, 9)
testthat::expect_true(lb1$found)
testthat::expect_identical(lb1$index, 2L)
testthat::expect_equal(lb1$value, "cc")
testthat::expect_true(ub1$found)
testthat::expect_identical(ub1$index, 3L)
testthat::expect_equal(ub1$value, "bbb")
testthat::expect_false(lb9$found)
testthat::expect_null(lb9$index)
})
testthat::test_that("pop_key/pop_all_key removal by key span", {
xs <- as_ordered_sequence(list("aa", "bb", "c", "dd", "e"), keys = c(2, 2, 1, 2, 1))
one <- pop_key(xs, 2)
testthat::expect_equal(one$value, "aa")
testthat::expect_equal(as.list(one$remaining), list("c", "e", "bb", "dd"))
all <- pop_all_key(xs, 2)
testthat::expect_s3_class(all$elements, "ordered_sequence")
testthat::expect_equal(as.list(all$elements), list("aa", "bb", "dd"))
testthat::expect_equal(as.list(all$remaining), list("c", "e"))
miss_one <- pop_key(xs, 99)
testthat::expect_null(miss_one$value)
testthat::expect_equal(as.list(miss_one$remaining), as.list(xs))
miss_all <- pop_all_key(xs, 99)
testthat::expect_s3_class(miss_all$elements, "ordered_sequence")
testthat::expect_identical(length(miss_all$elements), 0L)
testthat::expect_equal(as.list(miss_all$remaining), as.list(xs))
})
testthat::test_that("elements_between supports inclusivity flags", {
xs <- as_ordered_sequence(list("a", "bb", "cc", "ddd", "eeee"), keys = c(1, 2, 2, 3, 4))
e_closed <- elements_between(xs, 2, 3)
e_open_hi <- elements_between(xs, 2, 3, include_to = FALSE)
e_open_lo <- elements_between(xs, 2, 3, include_from = FALSE)
e_miss <- elements_between(xs, 9, 10)
testthat::expect_s3_class(e_closed, "ordered_sequence")
testthat::expect_s3_class(e_miss, "ordered_sequence")
testthat::expect_equal(as.list(e_closed), list("bb", "cc", "ddd"))
testthat::expect_equal(as.list(e_open_hi), list("bb", "cc"))
testthat::expect_equal(as.list(e_open_lo), list("ddd"))
testthat::expect_identical(length(e_miss), 0L)
})
testthat::test_that("peek_key/peek_all_key and pop_key are stable within duplicate key blocks", {
xs <- as_ordered_sequence(list("a1", "b1", "a2", "a3"), keys = c(1, 2, 1, 1))
testthat::expect_equal(peek_key(xs, 1), "a1")
peek_all <- peek_all_key(xs, 1)
testthat::expect_s3_class(peek_all, "ordered_sequence")
testthat::expect_equal(as.list(peek_all), list("a1", "a2", "a3"))
out <- pop_key(xs, 1)
testthat::expect_equal(out$value, "a1")
testthat::expect_equal(out$key, 1)
testthat::expect_equal(as.list(out$remaining), list("a2", "a3", "b1"))
testthat::expect_null(peek_key(xs, 9))
testthat::expect_identical(length(peek_all_key(xs, 9)), 0L)
miss <- pop_key(xs, 9)
testthat::expect_null(miss$value)
testthat::expect_null(miss$key)
testthat::expect_equal(as.list(miss$remaining), as.list(xs))
})
testthat::test_that("count helpers match range and key multiplicities", {
xs <- as_ordered_sequence(list("a", "bb", "cc", "ddd", "eeee"), keys = c(1, 2, 2, 3, 4))
testthat::expect_identical(count_key(xs, 2), 2L)
testthat::expect_identical(count_key(xs, 9), 0L)
testthat::expect_identical(count_between(xs, 2, 3), 3L)
testthat::expect_identical(count_between(xs, 2, 3, include_to = FALSE), 2L)
testthat::expect_identical(count_between(xs, 2, 3, include_from = FALSE), 1L)
testthat::expect_identical(count_between(xs, 9, 10), 0L)
})
testthat::test_that("split helpers preserve ordered_sequence subclass", {
xs <- as_ordered_sequence(list("a", "bb", "cc", "ddd", "eeee"), keys = c(1, 2, 2, 3, 4))
s <- split_by_predicate(xs, function(v) v >= 3L, ".size")
testthat::expect_s3_class(s$left, "ordered_sequence")
testthat::expect_s3_class(s$right, "ordered_sequence")
testthat::expect_equal(as.list(s$left), list("a", "bb"))
testthat::expect_equal(as.list(s$right), list("cc", "ddd", "eeee"))
sa <- split_around_by_predicate(xs, function(v) v >= 3L, ".size")
testthat::expect_s3_class(sa$left, "ordered_sequence")
testthat::expect_s3_class(sa$right, "ordered_sequence")
testthat::expect_equal(sa$value$value, "cc")
testthat::expect_equal(as.list(sa$left), list("a", "bb"))
testthat::expect_equal(as.list(sa$right), list("ddd", "eeee"))
})
testthat::test_that("order-breaking writes are blocked on ordered types", {
xs <- as_ordered_sequence(list("a", "b"), keys = c(1, 2))
testthat::expect_error(c(xs, xs), "not supported")
testthat::expect_error(push_back(xs, "c"), "not supported")
testthat::expect_error(push_front(xs, "z"), "not supported")
testthat::expect_error(insert_at(xs, 1, "z"), "not supported")
testthat::expect_error({ xs[[1]] <- "z" }, "not supported")
testthat::expect_error({ xs[1] <- list("z") }, "not supported")
testthat::expect_error({ xs$a <- "z" }, "not supported")
})
testthat::test_that("ordered replacement blocker messages never leak structural classes", {
xs <- as_ordered_sequence(list(a = "x", b = "y"), keys = c(1, 2))
msg1 <- testthat::expect_error({ xs[[1]] <- "z" })$message
msg2 <- testthat::expect_error({ xs[1] <- list("z") })$message
msg3 <- testthat::expect_error({ xs$a <- "z" })$message
testthat::expect_match(msg1, "ordered_sequence")
testthat::expect_match(msg2, "ordered_sequence")
testthat::expect_match(msg3, "ordered_sequence")
testthat::expect_false(grepl("Deep", msg1, fixed = TRUE))
testthat::expect_false(grepl("Deep", msg2, fixed = TRUE))
testthat::expect_false(grepl("Deep", msg3, fixed = TRUE))
})
testthat::test_that("ordered subsetting canonicalizes selector order and rejects duplicates", {
xs <- as_ordered_sequence(
list(a = "xa", b = "xb", c = "xc", d = "xd"),
keys = c(1, 2, 3, 4)
)
inc <- xs[c(1, 3)]
testthat::expect_s3_class(inc, "ordered_sequence")
testthat::expect_equal(as.list(inc), list(a = "xa", c = "xc"))
testthat::expect_identical(names(as.list(inc)), c("a", "c"))
by_name <- xs[c("a", "c")]
testthat::expect_equal(as.list(by_name), list(a = "xa", c = "xc"))
testthat::expect_identical(names(as.list(by_name)), c("a", "c"))
testthat::expect_equal(xs[[2]], "xb")
testthat::expect_equal(xs[["c"]], "xc")
testthat::expect_equal(xs$c, "xc")
lgl <- xs[c(TRUE, FALSE)]
testthat::expect_equal(as.list(lgl), list(a = "xa", c = "xc"))
testthat::expect_identical(names(as.list(lgl)), c("a", "c"))
reordered <- NULL
testthat::expect_warning(
{ reordered <- xs[c(3, 1)] },
"canonicalizes selector order"
)
testthat::expect_equal(as.list(reordered), list(a = "xa", c = "xc"))
reordered_name <- NULL
testthat::expect_warning(
{ reordered_name <- xs[c("c", "a")] },
"canonicalizes selector order"
)
testthat::expect_equal(as.list(reordered_name), list(a = "xa", c = "xc"))
testthat::expect_error(xs[c(2, 2)], "duplicate indices")
testthat::expect_error(xs[c("a", "a")], "duplicate indices")
testthat::expect_error(xs[c("a", "missing")], "Unknown element name")
})
testthat::test_that("pop helpers preserve ordered class", {
xs <- as_ordered_sequence(list("x1", "x2", "x3"), keys = c(1, 2, 3))
pf <- pop_front(xs)
pb <- pop_back(xs)
pm <- pop_at(xs, 2)
testthat::expect_identical(pf$value, "x1")
testthat::expect_s3_class(pf$remaining, "ordered_sequence")
testthat::expect_equal(as.list(pf$remaining), list("x2", "x3"))
testthat::expect_identical(pb$value, "x3")
testthat::expect_s3_class(pb$remaining, "ordered_sequence")
testthat::expect_equal(as.list(pb$remaining), list("x1", "x2"))
testthat::expect_identical(peek_at(xs, 2), "x2")
testthat::expect_identical(pm$value, "x2")
testthat::expect_s3_class(pm$remaining, "ordered_sequence")
testthat::expect_equal(as.list(pm$remaining), list("x1", "x3"))
})
testthat::test_that("fapply dispatches for ordered_sequence and no reset_ties arg", {
xs <- as_ordered_sequence(setNames(list("x1", "x2", "x3"), c("a", "b", "c")), keys = c(1, 1, 2))
xs_item <- fapply(xs, function(value, key, name) {
toupper(value)
})
testthat::expect_s3_class(xs_item, "ordered_sequence")
testthat::expect_equal(unname(as.list(xs_item)), list("X1", "X2", "X3"))
testthat::expect_identical(names(as.list(xs_item)), c("a", "b", "c"))
xs_tagged <- fapply(xs, function(value, key, name) {
paste(value, key, name, sep = "|")
})
testthat::expect_equal(unname(as.list(xs_tagged)), list("x1|1|a", "x2|1|b", "x3|2|c"))
testthat::expect_identical(names(as.list(xs_tagged)), c("a", "b", "c"))
testthat::expect_equal(count_key(xs_tagged, 1), 2L)
testthat::expect_equal(count_key(xs_tagged, 2), 1L)
testthat::expect_equal(peek_key(xs_tagged, 1), "x1|1|a")
testthat::expect_error(fapply(xs, 1), "`FUN` must be a function")
testthat::expect_error(fapply(xs, function(value, key, name) value, reset_ties = TRUE), "unused")
})
testthat::test_that("fapply can drop custom monoids for ordered_sequence", {
sum_item <- measure_monoid(`+`, 0, function(entry) as.numeric(entry$value))
xs <- add_monoids(as_ordered_sequence(list(10, 20), keys = c(1, 2)), list(sum_item = sum_item))
xs2 <- fapply(xs, function(value, key, name) value + 1, preserve_custom_monoids = FALSE)
ms <- attr(xs2, "monoids", exact = TRUE)
testthat::expect_true(!is.null(ms[[".size"]]))
testthat::expect_true(!is.null(ms[[".named_count"]]))
testthat::expect_true(!is.null(ms[[".oms_max_key"]]))
testthat::expect_true(is.null(ms[["sum_item"]]))
testthat::expect_error(node_measure(xs2, "sum_item"), "Missing cached measure")
testthat::expect_equal(as.list(xs2), list(11, 21))
})
testthat::test_that("ordered_sequence custom monoids accept entry measure arguments", {
xs <- add_monoids(
as_ordered_sequence(list(10, 20), keys = c(2, 1)),
list(
by_key = measure_monoid(`+`, 0, function(entry) as.numeric(entry$key))
)
)
testthat::expect_equal(node_measure(xs, "by_key"), 3)
})
testthat::test_that("ordered_sequence casts down to flexseq explicitly", {
sum_key <- measure_monoid(`+`, 0, function(entry) entry$key)
xs <- add_monoids(as_ordered_sequence(
setNames(list("x", "y"), c("kx", "ky")),
keys = c(2, 1)
), list(sum_key = sum_key))
fx <- as_flexseq(xs)
testthat::expect_s3_class(fx, "flexseq")
testthat::expect_false(inherits(fx, "ordered_sequence"))
testthat::expect_equal(fx[["kx"]], "x")
testthat::expect_equal(fx[["ky"]], "y")
ms <- names(attr(fx, "monoids", exact = TRUE))
testthat::expect_true(all(c(".size", ".named_count") %in% ms))
testthat::expect_false("sum_key" %in% ms)
testthat::expect_error(node_measure(fx, "sum_key"), "Missing cached measure")
testthat::expect_false(".oms_max_key" %in% ms)
})
testthat::test_that("ordered_sequence supports Date keys with stable tie handling", {
keys <- as.Date(c("2024-01-03", "2024-01-01", "2024-01-01", "2024-01-02"))
xs <- as_ordered_sequence(list("c", "a1", "a2", "b"), keys = keys)
testthat::expect_equal(as.list(xs), list("a1", "a2", "b", "c"))
testthat::expect_equal(peek_key(xs, as.Date("2024-01-01")), "a1")
lb <- lower_bound(xs, as.Date("2024-01-01"))
ub <- upper_bound(xs, as.Date("2024-01-01"))
testthat::expect_true(lb$found)
testthat::expect_identical(lb$index, 1L)
testthat::expect_equal(lb$value, "a1")
testthat::expect_s3_class(lb$key, "Date")
testthat::expect_true(ub$found)
testthat::expect_identical(ub$index, 3L)
testthat::expect_equal(ub$value, "b")
out <- pop_key(xs, as.Date("2024-01-01"))
testthat::expect_equal(out$value, "a1")
testthat::expect_s3_class(out$key, "Date")
testthat::expect_equal(as.list(out$remaining), list("a2", "b", "c"))
ys <- insert(xs, "a3", key = as.Date("2024-01-01"))
testthat::expect_equal(as.list(ys), list("a1", "a2", "a3", "b", "c"))
})
testthat::test_that("ordered_sequence supports POSIXct keys with stable tie handling", {
keys <- as.POSIXct(
c("2024-01-01 12:00:00", "2024-01-01 10:00:00", "2024-01-01 10:00:00"),
tz = "UTC"
)
xs <- as_ordered_sequence(list("late", "early1", "early2"), keys = keys)
testthat::expect_equal(as.list(xs), list("early1", "early2", "late"))
testthat::expect_equal(peek_key(xs, as.POSIXct("2024-01-01 10:00:00", tz = "UTC")), "early1")
out1 <- pop_key(xs, as.POSIXct("2024-01-01 10:00:00", tz = "UTC"))
out2 <- pop_key(out1$remaining, as.POSIXct("2024-01-01 10:00:00", tz = "UTC"))
testthat::expect_equal(out1$value, "early1")
testthat::expect_equal(out2$value, "early2")
testthat::expect_s3_class(out1$key, "POSIXct")
})
testthat::test_that("ordered_sequence rejects mixed key domains and missing keys", {
testthat::expect_error(
as_ordered_sequence(list("a", "b"), keys = list(1, "1")),
"Incompatible key type"
)
testthat::expect_error(
as_ordered_sequence(list("a", "b"), keys = list(1, as.Date("2024-01-01"))),
"Incompatible key type"
)
testthat::expect_error(
as_ordered_sequence(
list("a", "b"),
keys = list(as.Date("2024-01-01"), as.POSIXct("2024-01-01 00:00:00", tz = "UTC"))
),
"Incompatible key type"
)
xs_num <- as_ordered_sequence(list("a"), keys = 1)
xs_date <- as_ordered_sequence(list("a"), keys = as.Date("2024-01-01"))
testthat::expect_error(insert(xs_num, "b", key = "1"), "Incompatible key type")
testthat::expect_error(insert(xs_num, "b", key = as.Date("2024-01-01")), "Incompatible key type")
testthat::expect_error(
insert(xs_date, "b", key = as.POSIXct("2024-01-01 00:00:00", tz = "UTC")),
"Incompatible key type"
)
testthat::expect_error(
as_ordered_sequence(list("a"), keys = as.Date(NA)),
"`key` must be non-missing"
)
testthat::expect_error(
insert(xs_date, "b", key = as.Date(NA)),
"`key` must be non-missing"
)
})
testthat::test_that("ordered_sequence rejects non-empty keys when no elements are supplied", {
testthat::expect_error(
ordered_sequence(keys = c(1, 2)),
"`keys` must be empty when no elements are supplied"
)
testthat::expect_error(
as_ordered_sequence(list(), keys = c(1, 2)),
"`keys` must be empty when no elements are supplied"
)
})
testthat::test_that("ordered_sequence requires keys when elements are supplied", {
testthat::expect_error(
ordered_sequence("a", "b"),
"`keys` is required when elements are supplied"
)
testthat::expect_error(
as_ordered_sequence(list("a", "b"), keys = NULL),
"`keys` is required when elements are supplied"
)
})
testthat::test_that("ordered_sequence enforces keys length matches elements length", {
testthat::expect_error(
ordered_sequence("a", "b", keys = c(1)),
"`keys` length must match elements length"
)
testthat::expect_error(
as_ordered_sequence(list("a", "b"), keys = c(1, 2, 3)),
"`keys` length must match elements length"
)
})
testthat::test_that("ordered_sequence falls back to internal merge-sort when `c()` on keys fails", {
# The default sort path in .oms_order_entries uses `order(do.call(c, keys), idx)`.
# For exotic classes without a `c()` method, `do.call(c, keys)` returns a list
# which `order()` cannot handle; .oms_build_from_items then delegates to
# .oms_merge_sort_indices for a stable merge sort using the class's < / >.
# Class/methods are defined at file top-level (see below) — S3 dispatch for
# `Ops` needs them in an env the package can see, not inside test_that.
# Ensure the prerequisite holds (documents the test's premise).
testthat::expect_true(
inherits(tryCatch(order(do.call(c, list(mk_comp(1), mk_comp(2))), 1:2),
error = function(e) e),
"error")
)
# Large enough to force recursive merge-sort descent.
vals <- letters[1:7]
keys <- lapply(c(4, 1, 6, 3, 7, 2, 5), mk_comp)
xs <- as_ordered_sequence(vals, keys = keys)
testthat::expect_identical(length(xs), 7L)
# Sorted ascending by key val: 1,2,3,4,5,6,7 -> b,f,d,a,g,c,e
testthat::expect_identical(unlist(as.list(xs)), c("b", "f", "d", "a", "g", "c", "e"))
})
testthat::test_that("ordered_sequence supports ordered-factor keys (exotic-key slow path)", {
# Ordered factors aren't in the fast-domain set (numeric/character/logical/Date/POSIXct)
# but do support `<`/`>`. This exercises the slow-path key-compare and the
# non-fast-domain branch of .ft_normalize_scalar_orderable.
lvls <- c("low", "med", "high")
f <- factor(lvls, levels = lvls, ordered = TRUE)
xs <- as_ordered_sequence(c("L", "H", "M"), keys = c(f[1], f[3], f[2]))
testthat::expect_identical(length(xs), 3L)
# Sorted by factor level order: low, med, high.
testthat::expect_identical(unlist(as.list(xs)), c("L", "M", "H"))
# Key-based range query.
mid <- elements_between(xs, f[2], f[3])
testthat::expect_identical(unlist(as.list(mid)), c("M", "H"))
})
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.