# -- render.hypertext.tag --------------------------------------------------- test_that("render produces correct HTML for simple element", { node <- tags$div("hello") expect_equal(render(node), "
hello
") }) test_that("render produces correct HTML for element with attributes", { node <- tags$p(class = "lead", "text") expect_equal(render(node), '

text

') }) test_that("render handles empty element", { node <- tags$div() expect_equal(render(node), "
") }) test_that("render handles void elements as self-closing", { node <- tags$br() expect_equal(render(node), "
") }) test_that("render handles void element with attributes", { node <- tags$input(type = "text", name = "user") expect_equal(render(node), '') }) test_that("render handles nested elements", { node <- tags$div(tags$p("inner")) expect_equal(render(node), "

inner

") }) test_that("render handles deeply nested elements", { node <- tags$div(tags$ul(tags$li("item"))) expect_equal(render(node), "
") }) test_that("render handles multiple children", { node <- tags$div(tags$p("first"), tags$p("second")) expect_equal(render(node), "

first

second

") }) test_that("render handles mixed text and tag children", { node <- tags$p("Hello ", tags$strong("world"), "!") expect_equal(render(node), "

Hello world!

") }) test_that("render escapes text children", { node <- tags$p("") expect_equal( render(node), "

<script>alert('xss')</script>

" ) }) test_that("render escapes attribute values", { node <- tags$div(title = 'say "hi"') expect_equal(render(node), '
') }) test_that("render handles boolean attributes", { node <- tags$input(type = "checkbox", checked = TRUE) expect_equal(render(node), '') }) test_that("render handles NA as boolean attribute", { node <- tags$input(disabled = NA) expect_equal(render(node), "") }) test_that("render drops FALSE attributes", { node <- tags$input(type = "text", disabled = FALSE) expect_equal(render(node), '') }) test_that("render drops NULL attributes", { node <- tags$div(id = "x", class = NULL) expect_equal(render(node), '
') }) test_that("render collapses multi-value class attribute", { node <- tags$div(class = c("a", "b", "c")) expect_equal(render(node), '
') }) # -- render.default -------------------------------------------------------- test_that("render.default escapes text", { expect_equal(render("aa

b

") }) test_that("render.list handles mixed tags and text", { nodes <- list("hello ", tags$strong("world")) expect_equal(render(nodes), "hello world") }) test_that("render.list handles empty list", { expect_equal(render(list()), "") }) test_that("render.list handles single element", { nodes <- list(tags$div("one")) expect_equal(render(nodes), "
one
") }) # -- render with file (file output) ---------------------------------------- test_that("render writes tag to a file path and returns invisibly", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) node <- tags$div("hello") result <- withVisible(render(node, file = tmp)) expect_false(result$visible) expect_equal(result$value, "
hello
") expect_equal(readLines(tmp, warn = FALSE), "
hello
") }) test_that("render writes void element to a file path", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) node <- tags$br() render(node, file = tmp) expect_equal(readLines(tmp, warn = FALSE), "
") }) test_that("render writes nested HTML to a file path", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) page <- tags$html( tags$head(tags$title("Test")), tags$body(tags$h1("Hello")) ) render(page, file = tmp) expect_equal( readLines(tmp, warn = FALSE), "Test

Hello

" ) }) test_that("render.default writes text to a file path", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) result <- withVisible(render("aa

b

") expect_equal(readLines(tmp, warn = FALSE), "

a

b

") }) test_that("render writes to a connection object", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) con <- file(tmp, open = "w") on.exit(close(con), add = TRUE) node <- tags$div(class = "test", "content") render(node, file = con) # flush so readLines sees the output flush(con) expect_equal(readLines(tmp, warn = FALSE), '
content
') }) test_that("render with file = '' returns visibly (default behaviour)", { node <- tags$div("hello") result <- withVisible(render(node, file = "")) expect_true(result$visible) expect_equal(result$value, "
hello
") }) test_that("render overwrites existing file content", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) render(tags$p("first"), file = tmp) render(tags$p("second"), file = tmp) expect_equal(readLines(tmp, warn = FALSE), "

second

") }) # -- render with write_mode ------------------------------------------------ test_that("render overwrites file when write_mode = 'overwrite' explicitly", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) render(tags$p("first"), file = tmp) render(tags$p("second"), file = tmp, write_mode = "overwrite") expect_equal(readLines(tmp, warn = FALSE), "

second

") }) test_that("render.hypertext.tag appends to file when write_mode = 'append'", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) render(tags$p("first"), file = tmp) render(tags$p("second"), file = tmp, write_mode = "append") expect_equal( readLines(tmp, warn = FALSE), "

first

second

" ) }) test_that("render.default appends to file when write_mode = 'append'", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) render("hello", file = tmp) render(" world", file = tmp, write_mode = "append") expect_equal(readLines(tmp, warn = FALSE), "hello world") }) test_that("render.list appends to file when write_mode = 'append'", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) render(list(tags$p("a")), file = tmp) render(list(tags$p("b")), file = tmp, write_mode = "append") expect_equal(readLines(tmp, warn = FALSE), "

a

b

") }) test_that("render appends across multiple calls with write_mode = 'append'", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) render(tags$h1("Title"), file = tmp) render(tags$p("para 1"), file = tmp, write_mode = "append") render(tags$p("para 2"), file = tmp, write_mode = "append") expect_equal( readLines(tmp, warn = FALSE), "

Title

para 1

para 2

" ) }) test_that("render errors on invalid write_mode value", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) expect_error( render(tags$p("x"), file = tmp, write_mode = "bogus"), "arg" ) }) test_that("render appends to connection object with write_mode = 'append'", { tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) con <- file(tmp, open = "w") on.exit(close(con), add = TRUE) render(tags$p("first"), file = con) render(tags$p("second"), file = con, write_mode = "append") flush(con) expect_equal( readLines(tmp, warn = FALSE), "

first

second

" ) }) test_that("write_mode is ignored when file = '' (returns visibly)", { node <- tags$div("hello") result <- withVisible(render(node, file = "", write_mode = "append")) expect_true(result$visible) expect_equal(result$value, "
hello
") })