tests/testthat/test-builder-rust.R

# ───────────────────────── Rust backend FFI tests ─────────────────────────────

test_that("graph builder works for directed edge in reverse direction", {
  reg <- edge_registry_new()
  edge_registry_register_builtins(reg)
  expect_equal(edge_registry_len(reg), 6L)

  # Custom directed edge in reverse direction
  code_und <- edge_registry_register(
    reg,
    glyph = "<--",
    tail_mark = "arrow",
    head_mark = "tail",
    class = "directed",
    symmetric = FALSE
  )
  expect_true(is.integer(code_und) || is.double(code_und))

  b <- graph_builder_new(reg, n = 3L, simple = TRUE)

  # test if reverse directed edge works
  graph_builder_add_edges(
    b,
    from = c(0L),
    to = c(1L),
    etype = c(code_und) # undirected edge in the middle
  )

  # Build the class to verify it works
  class_label <- graph_builder_resolve_class(b, class = "PDAG")
  expect_equal(class_label, "PDAG")

  reset_caugi_registry()
})

test_that("queries work for DAGs and PDAGs", {
  # DAG EXAMPLE
  cg <- caugi(A %-->% B, class = "DAG")

  expect_null(parents(cg, index = 1L))
  expect_identical(children(cg, index = 1L), "B")
  expect_identical(parents(cg, index = 2L), "A")
  expect_null(children(cg, index = 2L))

  cg <- add_edges(cg, B %-->% C)
  # Session syncs automatically

  expect_null(parents(cg, index = 1L))
  expect_identical(children(cg, index = 1L), "B")
  expect_identical(parents(cg, index = 2L), "A")
  expect_identical(children(cg, index = 2L), "C")
  expect_identical(parents(cg, index = 3L), "B")
  expect_null(children(cg, index = 3L))

  # PDAG EXAMPLE
  cg <- caugi(A %-->% B, class = "PDAG")
  expect_null(parents(cg, index = 1L))
  expect_identical(children(cg, index = 1L), "B")
  expect_identical(parents(cg, index = 2L), "A")
  expect_null(children(cg, index = 2L))

  cg <- add_edges(cg, B %---% C)
  # Session syncs automatically

  expect_null(parents(cg, index = 1L))
  expect_identical(children(cg, index = 1L), "B")
  expect_identical(neighbors(cg, index = 2L, mode = "undirected"), "C")
})

test_that("rs_build compiles core and view lazily", {
  cg <- caugi(A %-->% B, class = "DAG")
  state_before <- rs_is_valid(cg@session)
  expect_true(state_before$core_valid)
  expect_false(state_before$view_valid)

  rs_build(cg@session)
  state_after <- rs_is_valid(cg@session)
  expect_true(state_after$core_valid)
  expect_true(state_after$view_valid)

  # idempotent call
  rs_build(cg@session)
  state_after2 <- rs_is_valid(cg@session)
  expect_true(state_after2$core_valid)
  expect_true(state_after2$view_valid)

  # mutation invalidates build
  cg <- add_edges(cg, B %-->% C)
  state_after_update <- rs_is_valid(cg@session)
  expect_true(state_after_update$core_valid)
  expect_false(state_after_update$view_valid)

  rs_build(cg@session)
  state_rebuilt <- rs_is_valid(cg@session)
  expect_true(state_rebuilt$core_valid)
  expect_true(state_rebuilt$view_valid)
})

test_that("edge registry seal works", {
  reg <- edge_registry_new()
  edge_registry_register_builtins(reg)
  expect_equal(edge_registry_len(reg), 6L)

  code_und <- edge_registry_register(
    reg,
    glyph = "x-x",
    tail_mark = "other",
    head_mark = "other",
    class = "undirected",
    symmetric = TRUE
  )
  expect_true(is.integer(code_und) || is.double(code_und))
  expect_equal(edge_registry_len(reg), 7L)

  edge_registry_seal(reg)

  expect_error(edge_registry_register(
    reg,
    glyph = "o-O",
    tail_mark = "other",
    head_mark = "other",
    class = "undirected",
    symmetric = TRUE
  ))

  expect_equal(edge_registry_code_of(reg, "x-x"), as.integer(code_und))
  expect_error(edge_registry_code_of(reg, "unknown"))
})

Try the caugi package in your browser

Any scripts or data that you put into this service are public.

caugi documentation built on Oct. 28, 2026, 1:07 a.m.