list_xml <- function(x) as_list(read_xml(x))

test_that("empty elements become empty lists", {
  expect_equal(list_xml("<x></x>"), list(x = list()))
  expect_equal(list_xml("<x><y/></x>"), list(x = list(y = list())))
  expect_equal(list_xml("<x><y><z/></y></x>"), list(x = list(y = list(z = list()))))
})

test_that("text nodes become character vectors", {
  expect_equal(list_xml("<x>a</x>"), list(x = list("a")))
  expect_equal(list_xml("<x><y>a</y></x>"), list(x = list(y = list("a"))))
})

test_that("cdata nodes become character vectors", {
  expect_equal(list_xml("<x><![CDATA[<y/>]]></x>"), list(x = list("<y/>")))
})

test_that("xml attributes become R attibutes", {
  expect_equal(list_xml("<x a='1' b='2'></x>"), list(x = structure(list(), a = "1", b = "2")))
})

test_that("xml names are preserved when attributes exist", {
  expect_equal(
    list_xml("<x a='1' b='2'><y>3</y><z>4</z></x>"),
    list(x = structure(list(y = list("3"), z = list("4")), a = "1", b = "2"))
  )
})

test_that("special attributes are escaped", {
  expect_equal(
    list_xml("<x a='1' b='2' names='esc'><y>3</y><z>4</z></x>"),
    list(x = structure(list(y = list("3"), z = list("4")), a = "1", b = "2", .names = "esc"))
  )
})

test_that("attributes in child nodes", {
  expect_equal(
    list_xml("<w aa = '0'><x a='1' b='2' names='esc'><y>3</y><z>4</z></x></w>"),
    list(w = structure(list(x = structure(list(y = list("3"), z = list("4")), a = "1", b = "2", .names = "esc")), aa = "0"))
  )
})
