@@ -300,6 +300,135 @@ describe('styling', () => {
300300 } ) ;
301301 } ) ;
302302
303+ describe ( 'non-string class keys' , ( ) => {
304+ it ( 'should allow null in a class array binding' , ( ) => {
305+ @Component ( {
306+ template : `<div [class]="['a', null, 'c']" [class.extra]="true"></div>` ,
307+ standalone : true ,
308+ } )
309+ class Cmp {
310+ }
311+
312+ const fixture = TestBed . createComponent ( Cmp ) ;
313+ fixture . detectChanges ( ) ;
314+ const div = fixture . nativeElement . querySelector ( 'div' ) ;
315+ expect ( div . getAttribute ( 'class' ) ) . toBe ( 'a c null extra' ) ;
316+ } ) ;
317+
318+ it ( 'should allow undefined in a class array binding' , ( ) => {
319+ @Component ( {
320+ template : `<div [class]="['a', undefined, 'c']" [class.extra]="true"></div>` ,
321+ standalone : true ,
322+ } )
323+ class Cmp {
324+ }
325+
326+ const fixture = TestBed . createComponent ( Cmp ) ;
327+ fixture . detectChanges ( ) ;
328+ const div = fixture . nativeElement . querySelector ( 'div' ) ;
329+ expect ( div . getAttribute ( 'class' ) ) . toBe ( 'a c undefined extra' ) ;
330+ } ) ;
331+
332+ it ( 'should allow zero in a class array binding' , ( ) => {
333+ @Component ( {
334+ template : `<div [class]="['a', 0, 'c']" [class.extra]="true"></div>` ,
335+ standalone : true ,
336+ } )
337+ class Cmp {
338+ }
339+
340+ const fixture = TestBed . createComponent ( Cmp ) ;
341+ fixture . detectChanges ( ) ;
342+ const div = fixture . nativeElement . querySelector ( 'div' ) ;
343+ expect ( div . getAttribute ( 'class' ) ) . toBe ( '0 a c extra' ) ;
344+ } ) ;
345+
346+ it ( 'should allow false in a class array binding' , ( ) => {
347+ @Component ( {
348+ template : `<div [class]="['a', false, 'c']" [class.extra]="true"></div>` ,
349+ standalone : true ,
350+ } )
351+ class Cmp {
352+ }
353+
354+ const fixture = TestBed . createComponent ( Cmp ) ;
355+ fixture . detectChanges ( ) ;
356+ const div = fixture . nativeElement . querySelector ( 'div' ) ;
357+ expect ( div . getAttribute ( 'class' ) ) . toBe ( 'a c false extra' ) ;
358+ } ) ;
359+
360+ it ( 'should ignore an empty string in a class array binding' , ( ) => {
361+ @Component ( {
362+ template : `<div [class]="['a', '', 'c']" [class.extra]="true"></div>` ,
363+ standalone : true ,
364+ } )
365+ class Cmp {
366+ }
367+
368+ const fixture = TestBed . createComponent ( Cmp ) ;
369+ fixture . detectChanges ( ) ;
370+ const div = fixture . nativeElement . querySelector ( 'div' ) ;
371+ expect ( div . getAttribute ( 'class' ) ) . toBe ( 'a c extra' ) ;
372+ } ) ;
373+
374+ it ( 'should ignore a string containing spaces in a class array binding' , ( ) => {
375+ @Component ( {
376+ template : `<div [class]="['a', 'hello there', 'c']" [class.extra]="true"></div>` ,
377+ standalone : true ,
378+ } )
379+ class Cmp {
380+ }
381+
382+ const fixture = TestBed . createComponent ( Cmp ) ;
383+ fixture . detectChanges ( ) ;
384+ const div = fixture . nativeElement . querySelector ( 'div' ) ;
385+ expect ( div . getAttribute ( 'class' ) ) . toBe ( 'a c extra' ) ;
386+ } ) ;
387+
388+ it ( 'should ignore a string containing spaces in a class object literal binding' , ( ) => {
389+ @Component ( {
390+ template :
391+ `<div [class]="{a: true, 'hello there': true, c: true}" [class.extra]="true"></div>` ,
392+ standalone : true ,
393+ } )
394+ class Cmp {
395+ }
396+
397+ const fixture = TestBed . createComponent ( Cmp ) ;
398+ fixture . detectChanges ( ) ;
399+ const div = fixture . nativeElement . querySelector ( 'div' ) ;
400+ expect ( div . getAttribute ( 'class' ) ) . toBe ( 'a c extra' ) ;
401+ } ) ;
402+
403+ it ( 'should ignore an object literal in a class array binding' , ( ) => {
404+ @Component ( {
405+ template : `<div [class]="['a', {foo: true}, 'c']" [class.extra]="true"></div>` ,
406+ standalone : true ,
407+ } )
408+ class Cmp {
409+ }
410+
411+ const fixture = TestBed . createComponent ( Cmp ) ;
412+ fixture . detectChanges ( ) ;
413+ const div = fixture . nativeElement . querySelector ( 'div' ) ;
414+ expect ( div . getAttribute ( 'class' ) ) . toBe ( 'a c extra' ) ;
415+ } ) ;
416+
417+ it ( 'should handle a string array in a class array binding' , ( ) => {
418+ @Component ( {
419+ template : `<div [class]="['a', ['foo', 'bar'], 'c']" [class.extra]="true"></div>` ,
420+ standalone : true ,
421+ } )
422+ class Cmp {
423+ }
424+
425+ const fixture = TestBed . createComponent ( Cmp ) ;
426+ fixture . detectChanges ( ) ;
427+ const div = fixture . nativeElement . querySelector ( 'div' ) ;
428+ expect ( div . getAttribute ( 'class' ) ) . toBe ( 'a c foo,bar extra' ) ;
429+ } ) ;
430+ } ) ;
431+
303432 it ( 'should bind [class] as input to directive' , ( ) => {
304433 @Component ( {
305434 template : `
0 commit comments