11import gc
2- import asyncio
32from weakref import finalize
43
54import pytest
65
76import idom
87from idom .core .layout import LayoutUpdate
98
10- from .utils import RenderHistory
9+ from tests .general_utils import assert_unordered_equal
10+
11+ from .utils import HookCatcher
1112
1213
1314def test_layout_repr ():
@@ -27,104 +28,79 @@ def test_layout_expects_abstract_element():
2728 idom .Layout (idom .html .div ())
2829
2930
30- async def test_layout_has_event_loop (event_loop ):
31- @idom .element
32- async def MyElement ():
33- return idom .html .div ()
34-
35- async with idom .Layout (MyElement ()) as layout :
36- assert layout .loop is event_loop
37- # await the render since creating the layout schedules a render task
38- await layout .render ()
39-
40-
41- async def test_layout_cancels_renders_on_close ():
42- event_that_is_never_set = asyncio .Event ()
43- render_is_cancelled = asyncio .Event ()
44-
45- @idom .element
46- async def MyElement ():
47- try :
48- await event_that_is_never_set .wait ()
49- finally :
50- render_is_cancelled .set ()
51-
52- async with idom .Layout (MyElement ()):
53- await asyncio .sleep (0.1 )
54-
55- await render_is_cancelled .wait ()
56-
57-
5831async def test_simple_layout ():
5932 set_state_hook = idom .Ref (None )
6033
6134 @idom .element
62- async def SimpleElement (tag ):
63- tag , set_tag = idom .hooks .use_state (tag )
64- set_state_hook .current = set_tag
35+ async def SimpleElement ():
36+ tag , set_state_hook .current = idom .hooks .use_state ("div" )
6537 return idom .vdom (tag )
6638
67- element = SimpleElement ("div" )
68- async with idom . Layout ( element ) as layout :
39+ async with idom . Layout ( SimpleElement ()) as layout :
40+ path , changes = await layout . render ()
6941
70- src , new , old , errors = await layout .render ()
71- assert src == element .id
72- assert new == {element .id : {"tagName" : "div" }}
73- assert old == []
74- assert errors == []
42+ assert path == ""
43+ assert_unordered_equal (
44+ changes ,
45+ [
46+ {"op" : "add" , "path" : "/eventHandlers" , "value" : {}},
47+ {"op" : "add" , "path" : "/tagName" , "value" : "div" },
48+ ],
49+ )
7550
7651 set_state_hook .current ("table" )
52+ path , changes = await layout .render ()
7753
78- src , new , old , errors = await layout .render ()
79- assert src == element .id
80- assert new == {element .id : {"tagName" : "table" }}
81- assert old == []
82- assert errors == []
54+ assert path == ""
55+ assert changes == [{"op" : "replace" , "path" : "/tagName" , "value" : "table" }]
8356
8457
8558async def test_nested_element_layout ():
59+ parent_set_state = idom .Ref (None )
60+ child_set_state = idom .Ref (None )
8661
87- history = RenderHistory ()
88-
89- @history .track ("parent" )
9062 @idom .element
9163 async def Parent ():
92- return idom .html .div ([Child ()])
64+ state , parent_set_state .current = idom .hooks .use_state (0 )
65+ return idom .html .div (state , Child ())
9366
94- @history .track ("child" )
9567 @idom .element
9668 async def Child ():
97- return idom .html .div ()
69+ state , child_set_state .current = idom .hooks .use_state (0 )
70+ return idom .html .div (state )
9871
9972 async with idom .Layout (Parent ()) as layout :
10073
101- src , new , old , errors = await layout .render ()
74+ path , changes = await layout .render ()
10275
103- assert src == history .parent_1 .id
104- assert new == {
105- history .parent_1 .id : {
106- "tagName" : "div" ,
107- "children" : [{"data" : history .child_1 .id , "type" : "ref" }],
108- },
109- history .child_1 .id : {"tagName" : "div" },
110- }
111- assert old == []
112- assert errors == []
76+ assert path == ""
77+ assert_unordered_equal (
78+ changes ,
79+ [
80+ {"op" : "add" , "path" : "/tagName" , "value" : "div" },
81+ {
82+ "op" : "add" ,
83+ "path" : "/children" ,
84+ "value" : [
85+ "0" ,
86+ {"children" : ["0" ], "eventHandlers" : {}, "tagName" : "div" },
87+ ],
88+ },
89+ {"op" : "add" , "path" : "/eventHandlers" , "value" : {}},
90+ ],
91+ )
11392
114- layout .update (history .parent_1 )
93+ parent_set_state .current (1 )
94+ path , changes = await layout .render ()
11595
116- src , new , old , errors = await layout .render ()
96+ assert path == ""
97+ assert changes == [{"op" : "replace" , "path" : "/children/0" , "value" : "1" }]
11798
118- assert src == history .parent_1 .id
119- assert new == {
120- history .parent_1 .id : {
121- "tagName" : "div" ,
122- "children" : [{"data" : history .child_2 .id , "type" : "ref" }],
123- },
124- history .child_2 .id : {"tagName" : "div" },
125- }
126- assert old == [history .child_1 .id ]
127- assert errors == []
99+ child_set_state .current (1 )
100+ path , changes = await layout .render ()
101+
102+ assert path == "/children/1"
103+ assert changes == [{"op" : "replace" , "path" : "/children/0" , "value" : "1" }]
128104
129105
130106async def test_layout_render_error_has_partial_update ():
@@ -220,11 +196,11 @@ async def Outer():
220196 live_elements .add (element .id )
221197 finalize (element , live_elements .remove , element .id )
222198
223- update = idom .hooks .use_update ()
199+ hook = idom .hooks .current_hook ()
224200
225201 @idom .event (target_id = "force-update" )
226202 async def force_update ():
227- update ()
203+ hook . schedule_render ()
228204
229205 return idom .html .div ({"onEvent" : force_update }, Inner ())
230206
0 commit comments