11/** @jsx h */
22
3- import { CDATA , html as h } from './html'
3+ import { hArgumentParser } from './h'
4+ import { CDATA , html as h , markup } from './html'
45
5- describe ( 'hTML ' , ( ) => {
6+ describe ( 'html ' , ( ) => {
67 it ( 'should generate a string' , ( ) => {
78 const s = h ( 'a' , { href : 'example.com' } , 'Welcome & Hello & Ciao' )
89 expect ( s ) . toEqual (
@@ -23,7 +24,7 @@ describe('hTML', () => {
2324 const s = (
2425 < a href = "example.com" x = "x" hidden = { false } { ...spread } >
2526 < hr myCaseSensitiveAttribute = "1" />
26- { null && 'This is invisible' }
27+ { false && 'This is invisible' }
2728 < b > Welcome</ b >
2829 </ a >
2930 )
@@ -42,4 +43,60 @@ describe('hTML', () => {
4243 `"<div><![CDATA[<b>Do not escape! & </b>]]></div>"` ,
4344 )
4445 } )
46+
47+ it ( 'should handle style attribute with various cases' , ( ) => {
48+ // Style with null/undefined values
49+ expect (
50+ h ( 'div' , { style : { color : 'red' , margin : null , padding : undefined } } ) ,
51+ ) . toBe ( '<div style="color:red"></div>' )
52+ // Style with number (should add px)
53+ expect ( h ( 'div' , { style : { width : 10 , height : 0 } } ) ) . toBe (
54+ '<div style="width:10px;height:0px"></div>' ,
55+ )
56+ // Style with camelCase (should convert to kebab-case)
57+ expect ( h ( 'div' , { style : { backgroundColor : 'blue' } } ) ) . toBe (
58+ '<div style="background-color:blue"></div>' ,
59+ )
60+ // Style with empty object (should not add style)
61+ expect ( h ( 'div' , { style : { } } ) ) . toBe ( '<div></div>' )
62+ } )
63+
64+ it ( 'should handle children as arrays, nested arrays, and skip null/false' , ( ) => {
65+ expect ( h ( 'div' , null , [ 'a' , null , false , h ( 'b' , null , 1 ) ] ) ) . toBe (
66+ '<div>a<b>1</b></div>' ,
67+ )
68+ } )
69+
70+ it ( 'should not escape children that are strings starting/ending with < >' , ( ) => {
71+ expect ( h ( 'div' , null , '<b>raw</b>' ) ) . toBe ( '<div><b>raw</b></div>' )
72+ } )
73+
74+ it ( 'should not escape children for script/style tags' , ( ) => {
75+ expect ( h ( 'script' , null , 'if (a < b) { alert(1) }' ) ) . toBe (
76+ '<script>if (a < b) { alert(1) }</script>' ,
77+ )
78+ expect ( h ( 'style' , null , 'body { color: red; }' ) ) . toBe (
79+ '<style>body { color: red; }</style>' ,
80+ )
81+ } )
82+
83+ it ( 'should stringify and escape children that are objects or numbers' , ( ) => {
84+ expect ( h ( 'div' , null , 123 ) ) . toBe ( '<div>123</div>' )
85+ expect ( h ( 'div' , null , { toString : ( ) => '<foo>' } ) ) . toBe ( '<div><foo></div>' )
86+ } )
87+
88+ it ( 'should handle xmlMode and self-closing tags' , ( ) => {
89+ // xmlMode true, no children
90+ expect ( hArgumentParser ( 'img' , { src : 'x.png' } ) ) . toBeDefined ( )
91+ expect ( markup ( true , 'img' , { src : 'x.png' } , undefined ) ) . toBe ( '<img src="x.png" />' )
92+
93+ // xmlMode true, with children
94+ expect ( markup ( true , 'div' , { } , [ 'foo' ] ) ) . toBe ( '<div>foo</div>' )
95+
96+ // xmlMode false, self-closing tag
97+ expect ( markup ( false , 'img' , { src : 'x.png' } , undefined ) ) . toBe ( '<img src="x.png">' )
98+
99+ // cdata
100+ expect ( markup ( false , 'cdata' , { } , 'foo' ) ) . toBe ( '<![CDATA[foo]]>' )
101+ } )
45102} )
0 commit comments