@@ -145,6 +145,10 @@ def parse_many(first, *others):
145145 assert parse_many ("a:lang(fr)" ) == ["Function[Element[a]:lang(['fr'])]" ]
146146 assert parse_many ('div:contains("foo")' ) == ["Function[Element[div]:contains(['foo'])]" ]
147147 assert parse_many ("div#foobar" ) == ["Hash[Element[div]#foobar]" ]
148+ assert parse_many (":not(a > b)" ) == ["Negation[Element[*]:not(Element[a] > Element[b])]" ]
149+ assert parse_many (":not(a + b)" ) == ["Negation[Element[*]:not(Element[a] + Element[b])]" ]
150+ assert parse_many (":not(a ~ b)" ) == ["Negation[Element[*]:not(Element[a] ~ Element[b])]" ]
151+ assert parse_many (":not(a b)" ) == ["Negation[Element[*]:not(Element[a] Element[b])]" ]
148152 assert parse_many ("div:not(div.foo)" ) == [
149153 "Negation[Element[div]:not(Class[Element[div].foo])]"
150154 ]
@@ -391,10 +395,8 @@ def get_error(css):
391395 assert get_error ("> div p" ) == ("Expected selector, got <DELIM '>' at 0>" )
392396
393397 # Unsupported :has() with several arguments
394- assert get_error (':has(a, b)' ) == (
395- "Expected an argument, got <DELIM ',' at 6>" )
396- assert get_error (':has()' ) == (
397- "Expected selector, got <EOF at 0>" )
398+ assert get_error (":has(a, b)" ) == ("Expected an argument, got <DELIM ',' at 6>" )
399+ assert get_error (":has()" ) == ("Expected selector, got <EOF at 0>" )
398400
399401 def test_translation (self ):
400402 def xpath (css ):
@@ -470,12 +472,23 @@ def xpath(css):
470472 assert xpath ("e:EmPTY" ) == ("e[not(*) and not(string-length())]" )
471473 assert xpath ("e:root" ) == ("e[not(parent::*)]" )
472474 assert xpath ("e:hover" ) == ("e[0]" ) # never matches
475+ assert xpath ("*:not(a > b)" ) == (
476+ "*[not([a] and parent::*[b])]"
477+ ) # select anything that is not b or doesn't have a parent a
478+ assert xpath ("*:not(a + b)" ) == (
479+ "*[not([a] and following-sibling::*[position()=1 and b])]"
480+ ) # select anything that is not b or doesn't have an immediate sibling a
481+ assert xpath ("*:not(a ~ b)" ) == (
482+ "*[not([a] and following-sibling::*[b])]"
483+ ) # select anything that is not b or doesn't have a sibling a
484+ assert xpath ("*:not(a b)" ) == (
485+ '*[not(name()="b" and ancestor::*[name()="a"])]'
486+ ) # select anything that is not b or doesn't have a ancestor a
473487 assert xpath ("e:has(> f)" ) == "e[./f]"
474488 assert xpath ("e:has(f)" ) == "e[descendant::f]"
475489 assert xpath ("e:has(~ f)" ) == "e[following-sibling::f]"
476490 assert (
477- xpath ("e:has(+ f)" )
478- == "e[following-sibling::*[(name() = 'f') and (position() = 1)]]"
491+ xpath ("e:has(+ f)" ) == "e[following-sibling::*[(name() = 'f') and (position() = 1)]]"
479492 )
480493 assert xpath ('e:contains("foo")' ) == ("e[contains(., 'foo')]" )
481494 assert xpath ("e:ConTains(foo)" ) == ("e[contains(., 'foo')]" )
0 commit comments