@@ -145,6 +145,10 @@ def parse_many(first, *others):
145
145
'Hash[Element[div]#foobar]' ]
146
146
assert parse_many ('div:not(div.foo)' ) == [
147
147
'Negation[Element[div]:not(Class[Element[div].foo])]' ]
148
+ assert parse_many ('div:is(.foo, #bar)' ) == [
149
+ 'Matching[Element[div]:is(Class[Element[*].foo], Hash[Element[*]#bar])]' ]
150
+ assert parse_many (':is(:hover, :visited)' ) == [
151
+ 'Matching[Element[*]:is(Pseudo[Element[*]:hover], Pseudo[Element[*]:visited])]' ]
148
152
assert parse_many ('td ~ th' ) == [
149
153
'CombinedSelector[Element[td] ~ Element[th]]' ]
150
154
assert parse_many (':scope > foo' ) == [
@@ -270,6 +274,8 @@ def specificity(css):
270
274
assert specificity (':has(foo)' ) == (0 , 0 , 1 )
271
275
assert specificity (':has(> foo)' ) == (0 , 0 , 1 )
272
276
277
+ assert specificity (':is(.foo, #bar)' ) == (1 , 0 , 0 )
278
+ assert specificity (':is(:hover, :visited)' ) == (0 , 1 , 0 )
273
279
274
280
assert specificity ('foo:empty' ) == (0 , 1 , 1 )
275
281
assert specificity ('foo:before' ) == (0 , 0 , 2 )
@@ -307,6 +313,8 @@ def css2css(css, res=None):
307
313
css2css (':not(#foo)' )
308
314
css2css (':has(*)' )
309
315
css2css (':has(foo)' )
316
+ css2css (':is(#bar, .foo)' )
317
+ css2css (':is(:focused, :visited)' )
310
318
css2css ('foo:empty' )
311
319
css2css ('foo::before' )
312
320
css2css ('foo:empty::before' )
@@ -380,6 +388,10 @@ def get_error(css):
380
388
"Got pseudo-element ::before inside :not() at 12" )
381
389
assert get_error (':not(:not(a))' ) == (
382
390
"Got nested :not()" )
391
+ assert get_error (':is(:before)' ) == (
392
+ "Got pseudo-element ::before inside function" )
393
+ assert get_error (':is(a b)' ) == (
394
+ "Expected an argument, got <IDENT 'b' at 6>" )
383
395
assert get_error (':scope > div :scope header' ) == (
384
396
'Got immediate child pseudo-element ":scope" not at the start of a selector'
385
397
)
@@ -498,7 +510,7 @@ def xpath(css):
498
510
assert xpath ('e:not(:nth-child(odd))' ) == (
499
511
"e[not(count(preceding-sibling::*) mod 2 = 0)]" )
500
512
assert xpath ('e:nOT(*)' ) == (
501
- "e[0]" ) # never matches
513
+ "e[0]" ) # never matches
502
514
assert xpath ('e:has(> f)' ) == 'e[./f]'
503
515
assert xpath ('e:has(f)' ) == 'e[descendant::f]'
504
516
assert xpath ('e:has(~ f)' ) == 'e[following-sibling::f]'
@@ -875,6 +887,12 @@ def pcss(main, *selectors, **kwargs):
875
887
'first-li' , 'second-li' , 'li-div' ,
876
888
'fifth-li' , 'sixth-li' , 'seventh-li' ]
877
889
assert pcss ('ol:has(div)' ) == ['first-ol' ]
890
+ assert pcss (':is(#first-li, #second-li)' ) == [
891
+ 'first-li' , 'second-li' ]
892
+ assert pcss ('a:is(#name-anchor, #tag-anchor)' ) == [
893
+ 'name-anchor' , 'tag-anchor' ]
894
+ assert pcss (':is(.c)' ) == [
895
+ 'first-ol' , 'third-li' , 'fourth-li' ]
878
896
assert pcss ('ol.a.b.c > li.c:nth-child(3)' ) == ['third-li' ]
879
897
880
898
# Invalid characters in XPath element names, should not crash
0 commit comments