@@ -207,107 +207,60 @@ describe(":has", () => {
207207} ) ;
208208
209209describe ( ":lang" , ( ) => {
210- it ( "should match exact language" , ( ) => {
211- const dom = parseDocument ( '<div lang="en"><p>hello</p></div>' ) ;
212- const matches = CSSselect . selectAll < AnyNode , Element > ( ":lang(en)" , dom ) ;
213- expect ( matches ) . toHaveLength ( 2 ) ;
214- } ) ;
215-
216- it ( "should match language prefix" , ( ) => {
217- const dom = parseDocument ( '<div lang="en-US"><p>hello</p></div>' ) ;
218- const matches = CSSselect . selectAll < AnyNode , Element > ( ":lang(en)" , dom ) ;
219- expect ( matches ) . toHaveLength ( 2 ) ;
220- } ) ;
221-
222- it ( "should be case-insensitive" , ( ) => {
223- const dom = parseDocument ( '<div lang="en"><p>hello</p></div>' ) ;
224- expect (
225- CSSselect . selectAll < AnyNode , Element > ( ":lang(EN)" , dom ) ,
226- ) . toHaveLength ( 2 ) ;
227-
228- const dom2 = parseDocument ( '<div lang="EN-US"><p>hello</p></div>' ) ;
229- expect (
230- CSSselect . selectAll < AnyNode , Element > ( ":lang(en)" , dom2 ) ,
231- ) . toHaveLength ( 2 ) ;
232- } ) ;
233-
234- it ( "should inherit from ancestors" , ( ) => {
235- const dom = parseDocument (
236- '<div lang="fr"><section><p>bonjour</p></section></div>' ,
237- ) ;
210+ // Single fixture covering inheritance, override, and untagged elements.
211+ const langFixture = parseDocument (
212+ '<div lang="en"><p id="a">A</p><div lang="fr-BE"><p id="b">B</p></div></div><p id="c">C</p>' ,
213+ ) ;
214+
215+ it . each ( [
216+ // [selector, expected ids]
217+ [ ":lang(en)" , [ "a" ] ] ,
218+ [ ":lang(EN)" , [ "a" ] ] ,
219+ [ ":lang(fr)" , [ "b" ] ] ,
220+ [ ":lang(fr-BE)" , [ "b" ] ] ,
221+ [ ":lang(en, fr)" , [ "a" , "b" ] ] ,
222+ [ ":lang(de)" , [ ] ] ,
223+ ] ) ( "%s matches %j" , ( selector , expectedIds ) => {
238224 const matches = CSSselect . selectAll < AnyNode , Element > (
239- "p:lang(fr)" ,
240- dom ,
225+ `p ${ selector } ` ,
226+ langFixture ,
241227 ) ;
242- expect ( matches ) . toHaveLength ( 1 ) ;
243- } ) ;
244-
245- it ( "should not match different languages" , ( ) => {
246- const dom = parseDocument (
247- '<div lang="fr"><p>bonjour</p></div><div lang="en"><p>hello</p></div>' ,
228+ expect ( matches . map ( ( element ) => element . attribs [ "id" ] ) ) . toStrictEqual (
229+ expectedIds ,
248230 ) ;
249- const matches = CSSselect . selectAll < AnyNode , Element > ( ":lang(en)" , dom ) ;
250- expect ( matches ) . toHaveLength ( 2 ) ;
251- } ) ;
252-
253- it ( "should not match partial non-prefix" , ( ) => {
254- const dom = parseDocument ( '<div lang="enx"><p>hello</p></div>' ) ;
255- const matches = CSSselect . selectAll < AnyNode , Element > ( ":lang(en)" , dom ) ;
256- expect ( matches ) . toHaveLength ( 0 ) ;
257231 } ) ;
258232
259- it ( "should allow closer ancestor to override" , ( ) => {
260- const dom = parseDocument (
261- '<div lang="en"><div lang="fr"><p>bonjour</p></div></div>' ,
262- ) ;
233+ it ( "should not match untagged elements" , ( ) => {
263234 expect (
264- CSSselect . selectAll < AnyNode , Element > ( "p:lang(fr )" , dom ) ,
235+ CSSselect . selectAll < AnyNode , Element > ( "p:lang(en )" , langFixture ) ,
265236 ) . toHaveLength ( 1 ) ;
266- expect (
267- CSSselect . selectAll < AnyNode , Element > ( "p:lang(en)" , dom ) ,
268- ) . toHaveLength ( 0 ) ;
269- } ) ;
270-
271- it ( "should support comma-separated language ranges" , ( ) => {
272- const dom = parseDocument (
273- '<div lang="en"><p>hello</p></div><div lang="fr"><p>bonjour</p></div><div lang="de"><p>hallo</p></div>' ,
274- ) ;
275- const matches = CSSselect . selectAll < AnyNode , Element > (
276- ":lang(en, fr)" ,
277- dom ,
278- ) ;
279- expect ( matches ) . toHaveLength ( 4 ) ;
280237 } ) ;
281238
282- it ( "should use extended filtering (RFC 4647)" , ( ) => {
283- // :lang(de-DE) should match de-Latn-DE (skipping single-char subtags)
239+ it ( "should use extended filtering" , ( ) => {
284240 const dom = parseDocument (
285- '<p lang="de-DE">a</p><p lang="de-DE-1996">b</p><p lang="de- Latn-DE">c </p><p lang="de-Latf-DE">d</p><p lang="de- Latn-DE-1996">e </p>' ,
241+ '<p lang="de-DE">a</p><p lang="de-Latn-DE">b </p><p lang="de-Latn-DE-1996">c </p>' ,
286242 ) ;
287- const matches = CSSselect . selectAll < AnyNode , Element > (
288- ":lang(de-DE)" ,
289- dom ,
290- ) ;
291- expect ( matches ) . toHaveLength ( 5 ) ;
243+ expect (
244+ CSSselect . selectAll < AnyNode , Element > ( ":lang(de-DE)" , dom ) ,
245+ ) . toHaveLength ( 3 ) ;
292246 } ) ;
293247
294248 it ( "should support wildcard primary subtag" , ( ) => {
295249 const dom = parseDocument (
296- '<p lang="de-CH">a</p><p lang="it-CH">b</p><p lang="fr-CH">c</p><p lang="fr-FR">d</p>' ,
297- ) ;
298- const matches = CSSselect . selectAll < AnyNode , Element > (
299- ":lang(\\*-CH)" ,
300- dom ,
250+ '<p lang="de-CH">a</p><p lang="fr-CH">b</p><p lang="fr-FR">c</p>' ,
301251 ) ;
302- expect ( matches ) . toHaveLength ( 3 ) ;
252+ expect (
253+ CSSselect . selectAll < AnyNode , Element > ( ":lang(\\*-CH)" , dom ) ,
254+ ) . toHaveLength ( 2 ) ;
303255 } ) ;
304256
305- it ( "should support xml:lang attribute " , ( ) => {
306- const dom = parseDocument ( '<div xml:lang="ja"><p>hello </p></div>' , {
257+ it ( "should support xml:lang" , ( ) => {
258+ const dom = parseDocument ( '<div xml:lang="ja"><p>x </p></div>' , {
307259 xmlMode : true ,
308260 } ) ;
309- const matches = CSSselect . selectAll < AnyNode , Element > ( ":lang(ja)" , dom ) ;
310- expect ( matches ) . toHaveLength ( 2 ) ;
261+ expect (
262+ CSSselect . selectAll < AnyNode , Element > ( ":lang(ja)" , dom ) ,
263+ ) . toHaveLength ( 2 ) ;
311264 } ) ;
312265} ) ;
313266
0 commit comments