6
6
import idom
7
7
from idom .core .dispatcher import render_json_patch
8
8
from idom .core .hooks import LifeCycleHook
9
- from idom .testing import HookCatcher
9
+ from idom .testing import HookCatcher , assert_idom_did_log
10
10
from tests .general_utils import assert_same_items
11
11
12
12
@@ -79,89 +79,68 @@ def SimpleStatefulComponent():
79
79
assert first_hook is h
80
80
81
81
82
- def test_use_state_with_constructor (driver , display , driver_wait ):
82
+ async def test_use_state_with_constructor ():
83
83
constructor_call_count = idom .Ref (0 )
84
84
85
+ set_outer_state = idom .Ref ()
86
+ set_inner_key = idom .Ref ()
87
+ set_inner_state = idom .Ref ()
88
+
85
89
def make_default ():
86
90
constructor_call_count .current += 1
87
91
return 0
88
92
89
93
@idom .component
90
94
def Outer ():
91
- hook = idom .hooks .current_hook ()
92
-
93
- async def on_click (event ):
94
- hook .schedule_render ()
95
-
96
- return idom .html .div (
97
- idom .html .button (
98
- {"onClick" : on_click , "id" : "outer" }, "update outer (rerun constructor)"
99
- ),
100
- Inner (),
101
- )
95
+ state , set_outer_state .current = idom .use_state (0 )
96
+ inner_key , set_inner_key .current = idom .use_state ("first" )
97
+ return idom .html .div (state , Inner (key = inner_key ))
102
98
103
99
@idom .component
104
100
def Inner ():
105
- count , set_count = idom .hooks .use_state (make_default )
101
+ state , set_inner_state .current = idom .use_state (make_default )
102
+ return idom .html .div (state )
106
103
107
- async def on_click (event ):
108
- set_count (count + 1 )
109
-
110
- return idom .html .div (
111
- idom .html .button (
112
- {"onClick" : on_click , "id" : "inner" },
113
- "update inner with state constructor" ,
114
- ),
115
- idom .html .p ({"id" : "count-view" }, count ),
116
- )
117
-
118
- display (Outer )
104
+ with idom .Layout (Outer ()) as layout :
105
+ await layout .render ()
119
106
120
- outer = driver .find_element ("id" , "outer" )
121
- inner = driver .find_element ("id" , "inner" )
122
- count = driver .find_element ("id" , "count-view" )
107
+ assert constructor_call_count .current == 1
123
108
124
- driver_wait . until ( lambda d : constructor_call_count . current == 1 )
125
- driver_wait . until ( lambda d : count . get_attribute ( "innerHTML" ) == "0" )
109
+ set_outer_state . current ( 1 )
110
+ await layout . render ( )
126
111
127
- inner . click ()
112
+ assert constructor_call_count . current == 1
128
113
129
- driver_wait . until ( lambda d : constructor_call_count . current == 1 )
130
- driver_wait . until ( lambda d : count . get_attribute ( "innerHTML" ) == "1" )
114
+ set_inner_state . current ( 1 )
115
+ await layout . render ( )
131
116
132
- outer . click ()
117
+ assert constructor_call_count . current == 1
133
118
134
- driver_wait . until ( lambda d : constructor_call_count . current == 2 )
135
- driver_wait . until ( lambda d : count . get_attribute ( "innerHTML" ) == "0" )
119
+ set_inner_key . current ( "second" )
120
+ await layout . render ( )
136
121
137
- inner . click ()
122
+ assert constructor_call_count . current == 2
138
123
139
- driver_wait .until (lambda d : constructor_call_count .current == 2 )
140
- driver_wait .until (lambda d : count .get_attribute ("innerHTML" ) == "1" )
141
124
125
+ async def test_set_state_with_reducer_instead_of_value ():
126
+ count = idom .Ref ()
127
+ set_count = idom .Ref ()
142
128
143
- def test_set_state_with_reducer_instead_of_value (driver , display ):
144
129
def increment (count ):
145
130
return count + 1
146
131
147
132
@idom .component
148
133
def Counter ():
149
- count , set_count = idom .hooks .use_state (0 )
150
- return idom .html .button (
151
- {
152
- "id" : "counter" ,
153
- "onClick" : lambda event : set_count (increment ),
154
- },
155
- f"Count: { count } " ,
156
- )
157
-
158
- display (Counter )
134
+ count .current , set_count .current = idom .hooks .use_state (0 )
135
+ return idom .html .div (count .current )
159
136
160
- client_counter = driver .find_element ("id" , "counter" )
137
+ with idom .Layout (Counter ()) as layout :
138
+ await layout .render ()
161
139
162
- for i in range (3 ):
163
- assert client_counter .get_attribute ("innerHTML" ) == f"Count: { i } "
164
- client_counter .click ()
140
+ for i in range (4 ):
141
+ assert count .current == i
142
+ set_count .current (increment )
143
+ await layout .render ()
165
144
166
145
167
146
def test_set_state_checks_identity_not_equality (driver , display , driver_wait ):
@@ -356,15 +335,15 @@ def cleanup():
356
335
357
336
358
337
async def test_use_effect_cleanup_occurs_on_will_unmount ():
359
- outer_component_hook = HookCatcher ()
338
+ set_key = idom . Ref ()
360
339
component_did_render = idom .Ref (False )
361
340
cleanup_triggered = idom .Ref (False )
362
341
cleanup_triggered_before_next_render = idom .Ref (False )
363
342
364
343
@idom .component
365
- @outer_component_hook .capture
366
344
def OuterComponent ():
367
- return ComponentWithEffect ()
345
+ key , set_key .current = idom .use_state ("first" )
346
+ return ComponentWithEffect (key = key )
368
347
369
348
@idom .component
370
349
def ComponentWithEffect ():
@@ -387,7 +366,7 @@ def cleanup():
387
366
388
367
assert not cleanup_triggered .current
389
368
390
- outer_component_hook . latest . schedule_render ( )
369
+ set_key . current ( "second" )
391
370
await layout .render ()
392
371
393
372
assert cleanup_triggered .current
@@ -592,13 +571,13 @@ def bad_cleanup():
592
571
assert re .match ("Post-render effect .*?" , first_log_line )
593
572
594
573
595
- async def test_error_in_effect_pre_unmount_cleanup_is_gracefully_handled (caplog ):
596
- outer_component_hook = HookCatcher ()
574
+ async def test_error_in_effect_pre_unmount_cleanup_is_gracefully_handled ():
575
+ set_key = idom . Ref ()
597
576
598
577
@idom .component
599
- @outer_component_hook .capture
600
578
def OuterComponent ():
601
- return ComponentWithEffect ()
579
+ key , set_key .current = idom .use_state ("first" )
580
+ return ComponentWithEffect (key = key )
602
581
603
582
@idom .component
604
583
def ComponentWithEffect ():
@@ -611,13 +590,14 @@ def bad_cleanup():
611
590
612
591
return idom .html .div ()
613
592
614
- with idom .Layout (OuterComponent ()) as layout :
615
- await layout .render ()
616
- outer_component_hook .latest .schedule_render ()
617
- await layout .render () # no error
618
-
619
- first_log_line = next (iter (caplog .records )).msg .split ("\n " , 1 )[0 ]
620
- assert re .match ("Pre-unmount effect .*? failed" , first_log_line )
593
+ with assert_idom_did_log (
594
+ match_message = r"Pre-unmount effect .*? failed" ,
595
+ error_type = ValueError ,
596
+ ):
597
+ with idom .Layout (OuterComponent ()) as layout :
598
+ await layout .render ()
599
+ set_key .current ("second" )
600
+ await layout .render () # no error
621
601
622
602
623
603
async def test_use_reducer ():
0 commit comments