Subtitle
Immediate
context("adjacent sibling combinator") test_that("adjacent sibling combinator generates simplified XPath", { xpath <- function(css) { css_to_xpath(css, prefix = "") } # Simple element + element expect_that(xpath('a + b'), equals("a/following-sibling::*[1][self::b]")) # With attribute on right side expect_that(xpath('a + b[id]'), equals("a/following-sibling::*[1][self::b][(@id)]")) # With class on right side expect_that(xpath('a + b.test'), equals("a/following-sibling::*[1][self::b][(@class and contains(concat(' ', normalize-space(@class), ' '), ' test '))]")) # With ID on right side expect_that(xpath('a + b#myid'), equals("a/following-sibling::*[1][self::b][(@id = 'myid')]")) # With multiple attributes on right side expect_that(xpath('a + b[id][title]'), equals("a/following-sibling::*[1][self::b][(@id) and (@title)]")) # With class and attribute on right side expect_that(xpath('a + b.test[title]'), equals("a/following-sibling::*[1][self::b][(@class and contains(concat(' ', normalize-space(@class), ' '), ' test ')) and (@title)]")) # With conditions on both sides expect_that(xpath('a.link + b[id]'), equals("a[(@class and contains(concat(' ', normalize-space(@class), ' '), ' link '))]/following-sibling::*[1][self::b][(@id)]")) expect_that(xpath('a[href] + b.test'), equals("a[(@href)]/following-sibling::*[1][self::b][(@class and contains(concat(' ', normalize-space(@class), ' '), ' test '))]")) # With ID on left, class and attribute on right expect_that(xpath('div#main + p.intro[title]'), equals("div[(@id = 'main')]/following-sibling::*[1][self::p][(@class and contains(concat(' ', normalize-space(@class), ' '), ' intro ')) and (@title)]")) # Universal selector on right expect_that(xpath('h1 + *[rel=up]'), equals("h1/following-sibling::*[1][self::*][(@rel = 'up')]")) # Combined with child combinator expect_that(xpath('div > h1 + p'), equals("div/h1/following-sibling::*[1][self::p]")) expect_that(xpath('div#main > h1 + p[class]'), equals("div[(@id = 'main')]/h1/following-sibling::*[1][self::p][(@class)]")) # With descendant combinator expect_that(xpath('section a + b'), equals("section//a/following-sibling::*[1][self::b]")) # Complex: multiple combinators and conditions expect_that(xpath('article.post > h2.title + p.intro[data-info]'), equals("article[(@class and contains(concat(' ', normalize-space(@class), ' '), ' post '))]/h2[(@class and contains(concat(' ', normalize-space(@class), ' '), ' title '))]/following-sibling::*[1][self::p][(@class and contains(concat(' ', normalize-space(@class), ' '), ' intro ')) and (@data-info)]")) }) test_that("adjacent sibling combinator works correctly with querySelector", { skip_if_not_installed("XML") library(XML) # Test with immediate adjacent siblings doc1 <- htmlParse('
AB') results1 <- querySelectorAll(doc1, "a + b") expect_equal(length(results1), 1) expect_equal(xmlGetAttr(results1[[1]], "id"), "b1") # Test with intervening element (should NOT match) doc2 <- htmlParse('AImmediate
Not immediate
Immediate