@@ -9,9 +9,13 @@ import {
99 TagFunc ,
1010 JsxRef ,
1111 Options ,
12+ OptionsChildren ,
13+ ContextFunc ,
1214} from './index' ;
1315
1416describe ( 'Test Runtime' , ( ) => {
17+ beforeEach ( clearContext ) ;
18+
1519 test ( 'context' , ( ) => {
1620 const ctx = 1 ;
1721 setContext ( 'div' , ctx ) ;
@@ -20,6 +24,11 @@ describe('Test Runtime', () => {
2024 expect ( getContext ( ) ) . toBeNull ( ) ;
2125 } ) ;
2226
27+ test ( 'wrong context' , ( ) => {
28+ const ctx = { namespaceURI : '' } ;
29+ expect ( ( ) => setContext ( 'div' , ctx ) ) . toThrowError ( 'namespaceURI context property is reserved for internal use' ) ;
30+ } ) ;
31+
2332 test ( 'jsx children' , ( ) => {
2433 const testDivOptions = ( options : Options , html : string ) => {
2534 let r1 = jsx ( 'div' , options ) ;
@@ -112,8 +121,6 @@ describe('Test Runtime', () => {
112121
113122 test ( 'jsx with event' , ( ) => {
114123 const onclick = jest . fn ( ) ;
115-
116- let r : JsxRef = { } ;
117124 const r1 = jsx ( 'div' , { id : 1 , children : true , onclick } ) ;
118125 expect ( r1 instanceof HTMLDivElement ) . toBeTruthy ( ) ;
119126 const e1 = r1 as HTMLElement ;
@@ -126,7 +133,6 @@ describe('Test Runtime', () => {
126133 } ) ;
127134
128135 test ( 'jsx with attribute' , ( ) => {
129- let r : JsxRef = { } ;
130136 const r1 = jsx ( 'div' , { id : 1 , children : true , style : 'display: block' } ) ;
131137 expect ( r1 instanceof HTMLDivElement ) . toBeTruthy ( ) ;
132138 const e1 = r1 as HTMLElement ;
@@ -135,7 +141,6 @@ describe('Test Runtime', () => {
135141 } ) ;
136142
137143 test ( 'jsx with null attribute' , ( ) => {
138- let r : JsxRef = { } ;
139144 const r1 = jsx ( 'div' , { id : 1 , children : true , style : null } ) ;
140145 expect ( r1 instanceof HTMLDivElement ) . toBeTruthy ( ) ;
141146 const e1 = r1 as HTMLElement ;
@@ -144,42 +149,129 @@ describe('Test Runtime', () => {
144149 } ) ;
145150
146151 test ( 'jsx with undefined attribute' , ( ) => {
147- let r : JsxRef = { } ;
148152 const r1 = jsx ( 'div' , { id : 1 , children : true , style : undefined } ) ;
149153 expect ( r1 instanceof HTMLDivElement ) . toBeTruthy ( ) ;
150154 const e1 = r1 as HTMLElement ;
151155 expect ( e1 . outerHTML ) . toBe ( '<div id="1">true</div>' ) ;
152156 expect ( e1 . style . display ) . toBe ( '' )
153157 } ) ;
154158
159+ test ( 'jsx with namespace' , ( ) => {
160+ const fc : TagFunc = ( o : Options , ctx ?: any ) => ( o . children as Function ) ( ctx ) ;
161+
162+ setContext ( fc , { } ) ;
163+ const r1 = jsx ( fc , { children : jsx ( 'svg' , { id : 1 , children : jsx ( 'path' , { id : 1 , d : 'MZ' , fill : 'white' } ) , xmlns : 'http://www.w3.org/2000/svg' } ) } ) ;
164+
165+ expect ( r1 instanceof SVGElement ) . toBeTruthy ( ) ;
166+ const e1 = r1 as SVGElement ;
167+ expect ( e1 . outerHTML ) . toBe ( '<svg id="1" xmlns="http://www.w3.org/2000/svg"><path id="1" d="MZ" fill="white"></path></svg>' ) ;
168+ expect ( e1 . namespaceURI ) . toBe ( 'http://www.w3.org/2000/svg' ) ;
169+ expect ( e1 . firstChild instanceof Element ) . toBeTruthy ( ) ;
170+ const e2 = e1 . firstChild as Element ;
171+ expect ( e2 . namespaceURI ) . toBe ( 'http://www.w3.org/2000/svg' ) ;
172+ } ) ;
173+
174+ test ( 'jsx with nested namespaces' , ( ) => {
175+ const fc = ( o : OptionsChildren , ctx ?: any ) => ( o . children as ContextFunc ) ( ctx ) ;
176+
177+ setContext ( fc , { } ) ;
178+
179+ const nested = jsx ( 'h1' , { id : 31 , children : jsx ( 'h2' , { id : 32 , children : jsx ( 'h3' , { } ) , xmlns : null } ) , xmlns : '3' } ) ;
180+ const nested1 = jsx ( 'h1' , { id : 21 , children : jsx ( 'h2' , { id : 22 , children : jsx ( 'h3' , { children : nested } ) , xmlns : null } ) , xmlns : '' } ) ;
181+ const nested2 = jsx ( 'h1' , { id : 11 , children : jsx ( 'h2' , { id : 12 , children : jsx ( 'h3' , { children : nested1 } ) } ) , xmlns : '2' } ) ;
182+ const r1 = jsx ( fc , { children : jsx ( 'h1' , { id : 1 , children : jsx ( 'h2' , { id : 2 , children : jsx ( 'h3' , { children : nested2 } ) } ) , xmlns : '1' } ) } ) ;
183+
184+ expect ( r1 instanceof Element ) . toBeTruthy ( ) ;
185+ const e1 = r1 as Element ;
186+ expect ( e1 . outerHTML ) . toBe ( '<h1 id="1" xmlns="1"><h2 id="2"><h3><h1 id="11" xmlns="2"><h2 id="12"><h3><h1 id="21" xmlns=""><h2 id="22"><h3><h1 id="31" xmlns="3"><h2 id="32"><h3></h3></h2></h1></h3></h2></h1></h3></h2></h1></h3></h2></h1>' ) ;
187+ expect ( e1 . namespaceURI ) . toBe ( '1' ) ;
188+ expect ( e1 . firstChild instanceof Element ) . toBeTruthy ( ) ;
189+ const e2 = e1 . firstChild as Element ;
190+ expect ( e2 . namespaceURI ) . toBe ( '1' ) ;
191+ expect ( e2 . firstChild instanceof Element ) . toBeTruthy ( ) ;
192+ const e3 = e2 . firstChild as Element ;
193+ expect ( e3 . namespaceURI ) . toBe ( '1' ) ;
194+
195+ const e11 = e3 . firstChild as Element ;
196+ expect ( e11 . namespaceURI ) . toBe ( '2' ) ;
197+ expect ( e11 . firstChild instanceof Element ) . toBeTruthy ( ) ;
198+ const e12 = e11 . firstChild as Element ;
199+ expect ( e12 . namespaceURI ) . toBe ( '2' ) ;
200+ expect ( e12 . firstChild instanceof Element ) . toBeTruthy ( ) ;
201+ const e13 = e12 . firstChild as Element ;
202+ expect ( e13 . namespaceURI ) . toBe ( '2' ) ;
203+
204+ const e21 = e13 . firstChild as Element ;
205+ expect ( e21 . namespaceURI ) . toBeNull ( ) ;
206+ expect ( e21 . firstChild instanceof Element ) . toBeTruthy ( ) ;
207+ const e22 = e21 . firstChild as Element ;
208+ expect ( e22 . namespaceURI ) . toBeNull ( ) ;
209+ expect ( e22 . firstChild instanceof Element ) . toBeTruthy ( ) ;
210+ const e23 = e22 . firstChild as Element ;
211+ expect ( e23 . namespaceURI ) . toBeNull ( ) ;
212+
213+ const e31 = e23 . firstChild as Element ;
214+ expect ( e31 . namespaceURI ) . toBe ( '3' ) ;
215+ expect ( e31 . firstChild instanceof Element ) . toBeTruthy ( ) ;
216+ const e32 = e31 . firstChild as Element ;
217+ expect ( e32 . namespaceURI ) . toBe ( '3' ) ;
218+ expect ( e32 . firstChild instanceof Element ) . toBeTruthy ( ) ;
219+ const e33 = e32 . firstChild as Element ;
220+ expect ( e33 . namespaceURI ) . toBe ( '3' ) ;
221+ } ) ;
222+
223+ test ( 'exception without context' , ( ) => {
224+ expect ( ( ) => jsx ( 'svg' , { xmlns : '1' } ) ) . toThrowError ( 'Declaring a namespace on an element using xmlns: attribute requires context' ) ;
225+ } ) ;
226+
155227 test ( 'jsx with context' , ( ) => {
156228 const r1 = jsx ( 'div' , { id : 1 , children : null } ) ;
157229 expect ( r1 instanceof HTMLDivElement ) . toBeTruthy ( ) ;
158230 const e1 = r1 as HTMLElement ;
159231 expect ( e1 . outerHTML ) . toBe ( '<div id="1"></div>' ) ;
160232
161- const fc : TagFunc = ( ) => e1 ;
233+ const fc : TagFunc = ( options , ctx ) => ( ( e1 . innerHTML = ctx ?. content || '' ) , e1 ) ;
162234
163235 const r2 = jsx ( fc , { id : 2 } ) ;
164236 expect ( r2 instanceof HTMLDivElement ) . toBeTruthy ( ) ;
165237 const e2 = r2 as HTMLElement ;
166238 expect ( e2 . outerHTML ) . toBe ( '<div id="1"></div>' ) ;
167239
168- setContext ( 'div' , undefined ) ;
240+ setContext ( 'div' , true ) ;
169241 const r3 = jsx ( fc , { id : 3 } ) ;
170242 expect ( r3 instanceof Function ) . toBeTruthy ( ) ;
171- const rr3 = ( r3 as TagFunc ) ( { } , undefined ) ;
243+ const rr3 = ( r3 as ContextFunc ) ( { content : 'test' } ) ;
244+ expect ( getContext ( ) ) . not . toBe ( null ) ;
245+ clearContext ( ) ;
246+
172247 expect ( rr3 instanceof HTMLDivElement ) . toBeTruthy ( ) ;
173248 const e3 = rr3 as HTMLElement ;
174- expect ( e3 . outerHTML ) . toBe ( '<div id="1"></div>' ) ;
175- clearContext ( ) ;
249+ expect ( e3 . outerHTML ) . toBe ( '<div id="1">test</div>' ) ;
176250
177251 setContext ( fc , { } ) ;
178252 const r4 = jsx ( fc , { id : 4 } ) ;
179253 expect ( r4 instanceof HTMLDivElement ) . toBeTruthy ( ) ;
180254 const e4 = r4 as HTMLElement ;
181255 expect ( e4 . outerHTML ) . toBe ( '<div id="1"></div>' ) ;
182256 expect ( getContext ( ) ) . toBe ( null ) ;
257+
258+ setContext ( fc , { content : 'test' } ) ;
259+ const r5 = jsx ( fc , { id : 5 } ) ;
260+ expect ( r5 instanceof HTMLDivElement ) . toBeTruthy ( ) ;
261+ expect ( getContext ( ) ) . toBe ( null ) ;
262+ const e5 = r5 as HTMLElement ;
263+ expect ( e5 . outerHTML ) . toBe ( '<div id="1">test</div>' ) ;
264+
265+ setContext ( fc , undefined ) ;
266+ const r6 = jsx ( fc , { id : 5 } ) ;
267+ expect ( r6 instanceof Function ) . toBeTruthy ( ) ;
268+ const rr6 = ( r6 as ContextFunc ) ( { content : 'test' } ) ;
269+ expect ( getContext ( ) ) . not . toBe ( null ) ;
270+ clearContext ( ) ;
271+ expect ( getContext ( ) ) . toBe ( null ) ;
272+ expect ( rr6 instanceof HTMLDivElement ) . toBeTruthy ( ) ;
273+ const e6 = rr3 as HTMLElement ;
274+ expect ( e6 . outerHTML ) . toBe ( '<div id="1">test</div>' ) ;
183275 } ) ;
184276
185277 test ( 'Comment' , ( ) => {
@@ -205,9 +297,9 @@ describe('Test Runtime', () => {
205297 const f2 = Fragment ( { children : 'fragment2' } ) ;
206298 expect ( f2 instanceof Function ) . toBeTruthy ( ) ;
207299 const rf = ( f2 as TagFunc ) ( { } , undefined ) ;
300+ clearContext ( ) ;
208301
209302 expect ( rf instanceof DocumentFragment ) . toBeTruthy ( ) ;
210303 expect ( ( rf as DocumentFragment ) . firstChild ?. textContent ) . toBe ( 'fragment2' ) ;
211- clearContext ( ) ;
212304 } ) ;
213305} ) ;
0 commit comments