tests/testthat/test-roundtrip.R

test_that("raw round-trips for empty, tiny, and multi-chunk payloads", {
  p <- new_pair()
  for (msg in list("", "x", "hello world", strrep("A", 200000))) {
    ct <- age_encrypt_raw(charToRaw(msg), recipients = p$rec)
    expect_type(ct, "raw")
    pt <- age_decrypt_raw(ct, identities = p$id)
    expect_identical(rawToChar(pt), msg)
  }
})

test_that("armored output is PEM and returns raw, round-trips", {
  p <- new_pair()
  ct <- age_encrypt_raw(charToRaw("armored secret"), recipients = p$rec,
                        armor = TRUE)
  expect_type(ct, "raw")
  expect_match(rawToChar(ct), "^-----BEGIN AGE ENCRYPTED FILE-----")
  expect_identical(
    rawToChar(age_decrypt_raw(ct, identities = p$id)),
    "armored secret"
  )
})

test_that("age_decrypt_raw accepts an armored character scalar", {
  p <- new_pair()
  ct <- age_encrypt_text("via string", recipients = p$rec)
  # split into lines and drop the trailing newline, as readLines() would
  lines <- strsplit(sub("\n$", "", ct), "\n", fixed = TRUE)[[1]]
  expect_identical(
    rawToChar(age_decrypt_raw(lines, identities = p$id)),
    "via string"
  )
})

test_that("text round-trips and preserves UTF-8", {
  p <- new_pair()
  msg <- "café ☃ \U0001F510"
  ct <- age_encrypt_text(msg, recipients = p$rec)
  expect_type(ct, "character")
  out <- age_decrypt_text(ct, identities = p$id)
  expect_identical(out, msg)
  expect_identical(Encoding(out), "UTF-8")
})

test_that("age_decrypt_text rejects binary / non-UTF-8 payloads", {
  p <- new_pair()
  # embedded NUL
  ct1 <- age_encrypt_raw(as.raw(c(1, 0, 2)), recipients = p$rec)
  expect_error(age_decrypt_text(ct1, identities = p$id), class = "age_error_decrypt")
  # invalid UTF-8 byte sequence
  ct2 <- age_encrypt_raw(as.raw(c(0xff, 0xfe, 0x41)), recipients = p$rec)
  expect_error(age_decrypt_text(ct2, identities = p$id), class = "age_error_decrypt")
})

test_that("file round-trip with default suffixes", {
  p <- new_pair()
  f <- withr::local_tempfile()
  writeBin(charToRaw("file contents here"), f)
  enc <- age_encrypt_file(f, recipients = p$rec)
  expect_identical(enc, paste0(f, ".age"))
  dec <- age_decrypt_file(enc, output = withr::local_tempfile(),
                          identities = p$id)
  expect_identical(readBin(dec, "raw", 100), charToRaw("file contents here"))
})

test_that("multiple recipients can each decrypt", {
  a <- new_pair()
  b <- new_pair()
  ct <- age_encrypt_raw(charToRaw("shared"), recipients = c(a$rec, b$rec))
  expect_identical(rawToChar(age_decrypt_raw(ct, identities = a$id)), "shared")
  expect_identical(rawToChar(age_decrypt_raw(ct, identities = b$id)), "shared")
})

test_that("decrypt scans a multi-identity set for a match", {
  # Build a key file holding two identities; encrypt only to the second.
  kf1 <- withr::local_tempfile()
  kf2 <- withr::local_tempfile()
  age_keygen(kf1)
  age_keygen(kf2)
  combined <- withr::local_tempfile()
  writeLines(c(readLines(kf1), readLines(kf2)), combined)

  rec2 <- age_pubkey(age_identity(kf2))
  ct <- age_encrypt_raw(charToRaw("for the second key"), recipients = rec2)

  ids <- age_identity(combined) # holds both keys as one C-side array
  expect_identical(
    rawToChar(age_decrypt_raw(ct, identities = ids)),
    "for the second key"
  )
})

Try the agecrypt package in your browser

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

agecrypt documentation built on Aug. 5, 2026, 9:08 a.m.