1
1
import pytest
2
2
3
3
import dash_html_components as html
4
+
4
5
# import dash_core_components as dcc
5
6
import dash
6
7
from dash .dependencies import Input , Output , ALL , MATCH
14
15
def test_cbmo001_all_output (with_simple , dash_duo ):
15
16
app = dash .Dash (__name__ )
16
17
17
- app .layout = html .Div (children = [
18
- html .Button ("items" , id = "items" ),
19
- html .Button ("values" , id = "values" ),
20
- html .Div (id = "content" ),
21
- html .Div ("Output init" , id = "output" ),
22
- ])
18
+ app .layout = html .Div (
19
+ children = [
20
+ html .Button ("items" , id = "items" ),
21
+ html .Button ("values" , id = "values" ),
22
+ html .Div (id = "content" ),
23
+ html .Div ("Output init" , id = "output" ),
24
+ ]
25
+ )
23
26
24
27
@app .callback (Output ("content" , "children" ), [Input ("items" , "n_clicks" )])
25
28
def content (n1 ):
@@ -28,9 +31,10 @@ def content(n1):
28
31
# these two variants have identical results, but the internal behavior
29
32
# is different when you combine the callbacks.
30
33
if with_simple :
34
+
31
35
@app .callback (
32
36
[Output ({"i" : ALL }, "children" ), Output ("output" , "children" )],
33
- [Input ("values" , "n_clicks" ), Input ({"i" : ALL }, "id" )]
37
+ [Input ("values" , "n_clicks" ), Input ({"i" : ALL }, "id" )],
34
38
)
35
39
def content_and_output (n2 , content_ids ):
36
40
# this variant *does* get called with empty ALL, because of the
@@ -42,6 +46,7 @@ def content_and_output(n2, content_ids):
42
46
return content , sum (content )
43
47
44
48
else :
49
+
45
50
@app .callback (Output ({"i" : ALL }, "children" ), [Input ("values" , "n_clicks" )])
46
51
def content_inner (n2 ):
47
52
# this variant does NOT get called with empty ALL
@@ -71,7 +76,7 @@ def out2(contents):
71
76
["#values" , "4\n 4\n 4" , "12" ],
72
77
["#items" , "" , "0" ],
73
78
["#values" , "" , "0" ],
74
- ["#items" , "5" , "5" ]
79
+ ["#items" , "5" , "5" ],
75
80
]
76
81
for selector , content , output in actions :
77
82
dash_duo .find_element (selector ).click ()
@@ -85,32 +90,43 @@ def out2(contents):
85
90
def test_cbmo002_all_and_match_output (with_simple , dash_duo ):
86
91
app = dash .Dash (__name__ )
87
92
88
- app .layout = html .Div (children = [
89
- html .Button ("items" , id = "items" ),
90
- html .Button ("values" , id = "values" ),
91
- html .Div (id = "content" ),
92
- ])
93
+ app .layout = html .Div (
94
+ children = [
95
+ html .Button ("items" , id = "items" ),
96
+ html .Button ("values" , id = "values" ),
97
+ html .Div (id = "content" ),
98
+ ]
99
+ )
93
100
94
101
@app .callback (Output ("content" , "children" ), [Input ("items" , "n_clicks" )])
95
102
def content (n1 ):
96
103
return [
97
- html .Div ([
98
- html .Div (
99
- [html .Div (id = {"i" : i , "j" : j }) for i in range (((n1 or 0 ) + j ) % 4 )],
100
- className = "content{}" .format (j )
101
- ),
102
- html .Div (id = {"j" : j }, className = "output{}" .format (j )),
103
- html .Hr (),
104
- ])
104
+ html .Div (
105
+ [
106
+ html .Div (
107
+ [
108
+ html .Div (id = {"i" : i , "j" : j })
109
+ for i in range (((n1 or 0 ) + j ) % 4 )
110
+ ],
111
+ className = "content{}" .format (j ),
112
+ ),
113
+ html .Div (id = {"j" : j }, className = "output{}" .format (j )),
114
+ html .Hr (),
115
+ ]
116
+ )
105
117
for j in range (4 )
106
118
]
107
119
108
120
# these two variants have identical results, but the internal behavior
109
121
# is different when you combine the callbacks.
110
122
if with_simple :
123
+
111
124
@app .callback (
112
- [Output ({"i" : ALL , "j" : MATCH }, "children" ), Output ({"j" : MATCH }, "children" )],
113
- [Input ("values" , "n_clicks" ), Input ({"i" : ALL , "j" : MATCH }, "id" )]
125
+ [
126
+ Output ({"i" : ALL , "j" : MATCH }, "children" ),
127
+ Output ({"j" : MATCH }, "children" ),
128
+ ],
129
+ [Input ("values" , "n_clicks" ), Input ({"i" : ALL , "j" : MATCH }, "id" )],
114
130
)
115
131
def content_and_output (n2 , content_ids ):
116
132
# this variant *does* get called with empty ALL, because of the
@@ -122,9 +138,9 @@ def content_and_output(n2, content_ids):
122
138
return content , sum (content )
123
139
124
140
else :
141
+
125
142
@app .callback (
126
- Output ({"i" : ALL , "j" : MATCH }, "children" ),
127
- [Input ("values" , "n_clicks" )]
143
+ Output ({"i" : ALL , "j" : MATCH }, "children" ), [Input ("values" , "n_clicks" )]
128
144
)
129
145
def content_inner (n2 ):
130
146
# this variant does NOT get called with empty ALL
@@ -137,7 +153,7 @@ def content_inner(n2):
137
153
138
154
@app .callback (
139
155
Output ({"j" : MATCH }, "children" ),
140
- [Input ({"i" : ALL , "j" : MATCH }, "children" )]
156
+ [Input ({"i" : ALL , "j" : MATCH }, "children" )],
141
157
)
142
158
def out2 (contents ):
143
159
return sum (contents )
@@ -157,7 +173,7 @@ def out2(contents):
157
173
["#values" , [["4\n 4\n 4" , "12" ], ["" , "0" ], ["4" , "4" ], ["4\n 4" , "8" ]]],
158
174
["#items" , [["" , "0" ], ["4" , "4" ], ["4\n 4" , "8" ], ["4\n 4\n 4" , "12" ]]],
159
175
["#values" , [["" , "0" ], ["5" , "5" ], ["5\n 5" , "10" ], ["5\n 5\n 5" , "15" ]]],
160
- ["#items" , [["5" , "5" ], ["5\n 5" , "10" ], ["5\n 5\n 5" , "15" ], ["" , "0" ]]]
176
+ ["#items" , [["5" , "5" ], ["5\n 5" , "10" ], ["5\n 5\n 5" , "15" ], ["" , "0" ]]],
161
177
]
162
178
for selector , output_spec in actions :
163
179
dash_duo .find_element (selector ).click ()
@@ -171,19 +187,21 @@ def out2(contents):
171
187
def test_cbmo003_multi_all (dash_duo ):
172
188
app = dash .Dash (__name__ )
173
189
174
- app .layout = html .Div (children = [
175
- html .Button ("items" , id = "items" ),
176
- html .Button ("values" , id = "values" ),
177
- html .Div (id = "content1" ),
178
- html .Hr (),
179
- html .Div (id = "content2" ),
180
- html .Hr (),
181
- html .Div ("Output init" , id = "output" ),
182
- ])
190
+ app .layout = html .Div (
191
+ children = [
192
+ html .Button ("items" , id = "items" ),
193
+ html .Button ("values" , id = "values" ),
194
+ html .Div (id = "content1" ),
195
+ html .Hr (),
196
+ html .Div (id = "content2" ),
197
+ html .Hr (),
198
+ html .Div ("Output init" , id = "output" ),
199
+ ]
200
+ )
183
201
184
202
@app .callback (
185
203
[Output ("content1" , "children" ), Output ("content2" , "children" )],
186
- [Input ("items" , "n_clicks" )]
204
+ [Input ("items" , "n_clicks" )],
187
205
)
188
206
def content (n1 ):
189
207
c1 = [html .Div (id = {"i" : i }) for i in range (((n1 or 0 ) + 2 ) % 4 )]
@@ -192,7 +210,7 @@ def content(n1):
192
210
193
211
@app .callback (
194
212
[Output ({"i" : ALL }, "children" ), Output ({"j" : ALL }, "children" )],
195
- [Input ("values" , "n_clicks" )]
213
+ [Input ("values" , "n_clicks" )],
196
214
)
197
215
def content_inner (n2 ):
198
216
# this variant does NOT get called with empty ALL
@@ -206,7 +224,7 @@ def content_inner(n2):
206
224
207
225
@app .callback (
208
226
Output ("output" , "children" ),
209
- [Input ({"i" : ALL }, "children" ), Input ({"j" : ALL }, "children" )]
227
+ [Input ({"i" : ALL }, "children" ), Input ({"j" : ALL }, "children" )],
210
228
)
211
229
def out2 (ci , cj ):
212
230
return sum (ci ) + sum (cj )
@@ -232,7 +250,7 @@ def out2(ci, cj):
232
250
# all empty! we'll see an error logged if the callback was fired
233
251
["#items" , "" , "" , "0" ],
234
252
["#values" , "" , "" , "0" ],
235
- ["#items" , "7" , "9" , "16" ]
253
+ ["#items" , "7" , "9" , "16" ],
236
254
]
237
255
for selector , content1 , content2 , output in actions :
238
256
dash_duo .find_element (selector ).click ()
0 commit comments