##// END OF EJS Templates
Remove tests for 4-5 tuples, add tests for validate logic
Gordon Ball -
Show More
@@ -1,560 +1,504 b''
1 1 """Test interact and interactive."""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2014 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 from __future__ import print_function
15 15
16 16 from collections import OrderedDict
17 17
18 18 import nose.tools as nt
19 19 import IPython.testing.tools as tt
20 20
21 21 # from IPython.core.getipython import get_ipython
22 22 from IPython.html import widgets
23 23 from IPython.html.widgets import interact, interactive, Widget, interaction
24 24 from IPython.utils.py3compat import annotate
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Utility stuff
28 28 #-----------------------------------------------------------------------------
29 29
30 30 class DummyComm(object):
31 31 comm_id = 'a-b-c-d'
32 32 def send(self, *args, **kwargs):
33 33 pass
34 34
35 35 def close(self, *args, **kwargs):
36 36 pass
37 37
38 38 _widget_attrs = {}
39 39 displayed = []
40 40
41 41 def setup():
42 42 _widget_attrs['comm'] = Widget.comm
43 43 Widget.comm = DummyComm()
44 44 _widget_attrs['_ipython_display_'] = Widget._ipython_display_
45 45 def raise_not_implemented(*args, **kwargs):
46 46 raise NotImplementedError()
47 47 Widget._ipython_display_ = raise_not_implemented
48 48
49 49 def teardown():
50 50 for attr, value in _widget_attrs.items():
51 51 setattr(Widget, attr, value)
52 52
53 53 def f(**kwargs):
54 54 pass
55 55
56 56 def clear_display():
57 57 global displayed
58 58 displayed = []
59 59
60 60 def record_display(*args):
61 61 displayed.extend(args)
62 62
63 63 #-----------------------------------------------------------------------------
64 64 # Actual tests
65 65 #-----------------------------------------------------------------------------
66 66
67 67 def check_widget(w, **d):
68 68 """Check a single widget against a dict"""
69 69 for attr, expected in d.items():
70 70 if attr == 'cls':
71 71 nt.assert_is(w.__class__, expected)
72 72 else:
73 73 value = getattr(w, attr)
74 74 nt.assert_equal(value, expected,
75 75 "%s.%s = %r != %r" % (w.__class__.__name__, attr, value, expected)
76 76 )
77 77
78 78 def check_widgets(container, **to_check):
79 79 """Check that widgets are created as expected"""
80 80 # build a widget dictionary, so it matches
81 81 widgets = {}
82 82 for w in container.children:
83 83 widgets[w.description] = w
84 84
85 85 for key, d in to_check.items():
86 86 nt.assert_in(key, widgets)
87 87 check_widget(widgets[key], **d)
88 88
89 89
90 90 def test_single_value_string():
91 91 a = u'hello'
92 92 c = interactive(f, a=a)
93 93 w = c.children[0]
94 94 check_widget(w,
95 95 cls=widgets.TextWidget,
96 96 description='a',
97 97 value=a,
98 98 )
99 99
100 100 def test_single_value_bool():
101 101 for a in (True, False):
102 102 c = interactive(f, a=a)
103 103 w = c.children[0]
104 104 check_widget(w,
105 105 cls=widgets.CheckboxWidget,
106 106 description='a',
107 107 value=a,
108 108 )
109 109
110 110 def test_single_value_dict():
111 111 for d in [
112 112 dict(a=5),
113 113 dict(a=5, b='b', c=dict),
114 114 ]:
115 115 c = interactive(f, d=d)
116 116 w = c.children[0]
117 117 check_widget(w,
118 118 cls=widgets.DropdownWidget,
119 119 description='d',
120 120 values=d,
121 121 value=next(iter(d.values())),
122 122 )
123 123
124 124 def test_single_value_float():
125 125 for a in (2.25, 1.0, -3.5):
126 126 c = interactive(f, a=a)
127 127 w = c.children[0]
128 128 check_widget(w,
129 129 cls=widgets.FloatSliderWidget,
130 130 description='a',
131 131 value=a,
132 132 min= -a if a > 0 else 3*a,
133 133 max= 3*a if a > 0 else -a,
134 134 step=0.1,
135 135 readout=True,
136 136 )
137 137
138 138 def test_single_value_int():
139 139 for a in (1, 5, -3):
140 140 c = interactive(f, a=a)
141 141 nt.assert_equal(len(c.children), 1)
142 142 w = c.children[0]
143 143 check_widget(w,
144 144 cls=widgets.IntSliderWidget,
145 145 description='a',
146 146 value=a,
147 147 min= -a if a > 0 else 3*a,
148 148 max= 3*a if a > 0 else -a,
149 149 step=1,
150 150 readout=True,
151 151 )
152 152
153 153 def test_list_tuple_2_int():
154 154 with nt.assert_raises(ValueError):
155 155 c = interactive(f, tup=(1,1))
156 156 with nt.assert_raises(ValueError):
157 157 c = interactive(f, tup=(1,-1))
158 158 for min, max in [ (0,1), (1,10), (1,2), (-5,5), (-20,-19) ]:
159 159 c = interactive(f, tup=(min, max), lis=[min, max])
160 160 nt.assert_equal(len(c.children), 2)
161 161 d = dict(
162 162 cls=widgets.IntSliderWidget,
163 163 min=min,
164 164 max=max,
165 165 step=1,
166 166 readout=True,
167 167 )
168 168 check_widgets(c, tup=d, lis=d)
169 169
170 170 def test_list_tuple_3_int():
171 171 with nt.assert_raises(ValueError):
172 172 c = interactive(f, tup=(1,2,0))
173 173 with nt.assert_raises(ValueError):
174 174 c = interactive(f, tup=(1,2,-1))
175 175 for min, max, step in [ (0,2,1), (1,10,2), (1,100,2), (-5,5,4), (-100,-20,4) ]:
176 176 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
177 177 nt.assert_equal(len(c.children), 2)
178 178 d = dict(
179 179 cls=widgets.IntSliderWidget,
180 180 min=min,
181 181 max=max,
182 182 step=step,
183 183 readout=True,
184 184 )
185 185 check_widgets(c, tup=d, lis=d)
186 186
187 187 def test_list_tuple_2_float():
188 188 with nt.assert_raises(ValueError):
189 189 c = interactive(f, tup=(1.0,1.0))
190 190 with nt.assert_raises(ValueError):
191 191 c = interactive(f, tup=(0.5,-0.5))
192 192 for min, max in [ (0.5, 1.5), (1.1,10.2), (1,2.2), (-5.,5), (-20,-19.) ]:
193 193 c = interactive(f, tup=(min, max), lis=[min, max])
194 194 nt.assert_equal(len(c.children), 2)
195 195 d = dict(
196 196 cls=widgets.FloatSliderWidget,
197 197 min=min,
198 198 max=max,
199 199 step=.1,
200 200 readout=True,
201 201 )
202 202 check_widgets(c, tup=d, lis=d)
203 203
204 204 def test_list_tuple_3_float():
205 205 with nt.assert_raises(ValueError):
206 206 c = interactive(f, tup=(1,2,0.0))
207 207 with nt.assert_raises(ValueError):
208 208 c = interactive(f, tup=(-1,-2,1.))
209 209 with nt.assert_raises(ValueError):
210 210 c = interactive(f, tup=(1,2.,-1.))
211 211 for min, max, step in [ (0.,2,1), (1,10.,2), (1,100,2.), (-5.,5.,4), (-100,-20.,4.) ]:
212 212 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
213 213 nt.assert_equal(len(c.children), 2)
214 214 d = dict(
215 215 cls=widgets.FloatSliderWidget,
216 216 min=min,
217 217 max=max,
218 218 step=step,
219 219 readout=True,
220 220 )
221 221 check_widgets(c, tup=d, lis=d)
222 222
223 def test_list_tuple_4_int():
224 with nt.assert_raises(ValueError):
225 c = interactive(f, tup=(4, 3, 2, 1))
226 with nt.assert_raises(ValueError):
227 c = interactive(f, tup=(1, 2, 3, 2))
228 with nt.assert_raises(ValueError):
229 c = interactive(f, tup=(2, 1, 3, 4))
230 for min, low, high, max in [(0, 1, 2, 3), (0, 0, 0, 0), (1, 2, 2, 3), (-2, -1, 1, 2)]:
231 c = interactive(f, tup=(min, low, high, max), lis=[min, low, high, max])
232 nt.assert_equal(len(c.children), 2)
233 d = dict(
234 cls=widgets.IntRangeSliderWidget,
235 min=min,
236 max=max,
237 value=(low, high),
238 range=True,
239 readout=True
240 )
241 check_widgets(c, tup=d, lis=d)
242
243 def test_list_tuple_5_int():
244 with nt.assert_raises(ValueError):
245 c = interactive(f, tup=(1, 2, 3, 4, 0))
246 with nt.assert_raises(ValueError):
247 c = interactive(f, tup=(1, 2, 3, 4, -1))
248 for min, low, high, max, step in [(0, 1, 2, 3, 1), (0, 0, 0, 0, 1), (1, 2, 2, 3, 2), (-2, -1, 1, 2, 3)]:
249 c = interactive(f, tup=(min, low, high, max, step), lis=[min, low, high, max, step])
250 nt.assert_equal(len(c.children), 2)
251 d = dict(
252 cls=widgets.IntRangeSliderWidget,
253 min=min,
254 max=max,
255 value=(low, high),
256 step=step,
257 range=True,
258 readout=True
259 )
260 check_widgets(c, tup=d, lis=d)
261
262 def test_list_tuple_4_float():
263 with nt.assert_raises(ValueError):
264 c = interactive(f, tup=(4, 3., 2, 1))
265 with nt.assert_raises(ValueError):
266 c = interactive(f, tup=(1, 2, 3, 2.))
267 with nt.assert_raises(ValueError):
268 c = interactive(f, tup=(2, 1., 3, 4))
269 for min, low, high, max in [(0, 1., 2, 3), (0, 0, 0., 0), (1., 2., 2., 3.1415), (-2.5, -1, 1, 2.5)]:
270 c = interactive(f, tup=(min, low, high, max), lis=[min, low, high, max])
271 nt.assert_equal(len(c.children), 2)
272 d = dict(
273 cls=widgets.FloatRangeSliderWidget,
274 min=min,
275 max=max,
276 value=(low, high),
277 range=True,
278 readout=True
279 )
280 check_widgets(c, tup=d, lis=d)
281
282 def test_list_tuple_5_float():
283 with nt.assert_raises(ValueError):
284 c = interactive(f, tup=(1, 2., 3., 4, 0))
285 with nt.assert_raises(ValueError):
286 c = interactive(f, tup=(1, 2, 3., 4., -0.5))
287 for min, low, high, max, step in [(0, 1, 2, 3, 0.01), (0, 0, 0, 0, 0.1), (1, 2, 2, 3, 2.718), (-2, -1.5, 1.5, 2, 2)]:
288 c = interactive(f, tup=(min, low, high, max, step), lis=[min, low, high, max, step])
289 nt.assert_equal(len(c.children), 2)
290 d = dict(
291 cls=widgets.FloatRangeSliderWidget,
292 min=min,
293 max=max,
294 value=(low, high),
295 step=step,
296 range=True,
297 readout=True
298 )
299 check_widgets(c, tup=d, lis=d)
300
301 223 def test_list_tuple_str():
302 224 values = ['hello', 'there', 'guy']
303 225 first = values[0]
304 226 dvalues = OrderedDict((v,v) for v in values)
305 227 c = interactive(f, tup=tuple(values), lis=list(values))
306 228 nt.assert_equal(len(c.children), 2)
307 229 d = dict(
308 230 cls=widgets.DropdownWidget,
309 231 value=first,
310 232 values=dvalues
311 233 )
312 234 check_widgets(c, tup=d, lis=d)
313 235
314 236 def test_list_tuple_invalid():
315 237 for bad in [
316 238 (),
317 239 (5, 'hi'),
318 240 ('hi', 5),
319 241 ({},),
320 242 (None,),
321 243 ]:
322 244 with nt.assert_raises(ValueError):
323 245 print(bad) # because there is no custom message in assert_raises
324 246 c = interactive(f, tup=bad)
325 247
326 248 def test_defaults():
327 249 @annotate(n=10)
328 250 def f(n, f=4.5, g=1):
329 251 pass
330 252
331 253 c = interactive(f)
332 254 check_widgets(c,
333 255 n=dict(
334 256 cls=widgets.IntSliderWidget,
335 257 value=10,
336 258 ),
337 259 f=dict(
338 260 cls=widgets.FloatSliderWidget,
339 261 value=4.5,
340 262 ),
341 263 g=dict(
342 264 cls=widgets.IntSliderWidget,
343 265 value=1,
344 266 ),
345 267 )
346 268
347 269 def test_default_values():
348 270 @annotate(n=10, f=(0, 10.), g=5, h={'a': 1, 'b': 2}, j=['hi', 'there'])
349 271 def f(n, f=4.5, g=1, h=2, j='there'):
350 272 pass
351 273
352 274 c = interactive(f)
353 275 check_widgets(c,
354 276 n=dict(
355 277 cls=widgets.IntSliderWidget,
356 278 value=10,
357 279 ),
358 280 f=dict(
359 281 cls=widgets.FloatSliderWidget,
360 282 value=4.5,
361 283 ),
362 284 g=dict(
363 285 cls=widgets.IntSliderWidget,
364 286 value=5,
365 287 ),
366 288 h=dict(
367 289 cls=widgets.DropdownWidget,
368 290 values={'a': 1, 'b': 2},
369 291 value=2
370 292 ),
371 293 j=dict(
372 294 cls=widgets.DropdownWidget,
373 295 values={'hi':'hi', 'there':'there'},
374 296 value='there'
375 297 ),
376 298 )
377 299
378 300 def test_default_out_of_bounds():
379 301 @annotate(f=(0, 10.), h={'a': 1}, j=['hi', 'there'])
380 302 def f(f='hi', h=5, j='other'):
381 303 pass
382 304
383 305 c = interactive(f)
384 306 check_widgets(c,
385 307 f=dict(
386 308 cls=widgets.FloatSliderWidget,
387 309 value=5.,
388 310 ),
389 311 h=dict(
390 312 cls=widgets.DropdownWidget,
391 313 values={'a': 1},
392 314 value=1,
393 315 ),
394 316 j=dict(
395 317 cls=widgets.DropdownWidget,
396 318 values={'hi':'hi', 'there':'there'},
397 319 value='hi',
398 320 ),
399 321 )
400 322
401 323 def test_annotations():
402 324 @annotate(n=10, f=widgets.FloatTextWidget())
403 325 def f(n, f):
404 326 pass
405 327
406 328 c = interactive(f)
407 329 check_widgets(c,
408 330 n=dict(
409 331 cls=widgets.IntSliderWidget,
410 332 value=10,
411 333 ),
412 334 f=dict(
413 335 cls=widgets.FloatTextWidget,
414 336 ),
415 337 )
416 338
417 339 def test_priority():
418 340 @annotate(annotate='annotate', kwarg='annotate')
419 341 def f(kwarg='default', annotate='default', default='default'):
420 342 pass
421 343
422 344 c = interactive(f, kwarg='kwarg')
423 345 check_widgets(c,
424 346 kwarg=dict(
425 347 cls=widgets.TextWidget,
426 348 value='kwarg',
427 349 ),
428 350 annotate=dict(
429 351 cls=widgets.TextWidget,
430 352 value='annotate',
431 353 ),
432 354 )
433 355
434 356 @nt.with_setup(clear_display)
435 357 def test_decorator_kwarg():
436 358 with tt.monkeypatch(interaction, 'display', record_display):
437 359 @interact(a=5)
438 360 def foo(a):
439 361 pass
440 362 nt.assert_equal(len(displayed), 1)
441 363 w = displayed[0].children[0]
442 364 check_widget(w,
443 365 cls=widgets.IntSliderWidget,
444 366 value=5,
445 367 )
446 368
447 369 @nt.with_setup(clear_display)
448 370 def test_decorator_no_call():
449 371 with tt.monkeypatch(interaction, 'display', record_display):
450 372 @interact
451 373 def foo(a='default'):
452 374 pass
453 375 nt.assert_equal(len(displayed), 1)
454 376 w = displayed[0].children[0]
455 377 check_widget(w,
456 378 cls=widgets.TextWidget,
457 379 value='default',
458 380 )
459 381
460 382 @nt.with_setup(clear_display)
461 383 def test_call_interact():
462 384 def foo(a='default'):
463 385 pass
464 386 with tt.monkeypatch(interaction, 'display', record_display):
465 387 ifoo = interact(foo)
466 388 nt.assert_equal(len(displayed), 1)
467 389 w = displayed[0].children[0]
468 390 check_widget(w,
469 391 cls=widgets.TextWidget,
470 392 value='default',
471 393 )
472 394
473 395 @nt.with_setup(clear_display)
474 396 def test_call_interact_kwargs():
475 397 def foo(a='default'):
476 398 pass
477 399 with tt.monkeypatch(interaction, 'display', record_display):
478 400 ifoo = interact(foo, a=10)
479 401 nt.assert_equal(len(displayed), 1)
480 402 w = displayed[0].children[0]
481 403 check_widget(w,
482 404 cls=widgets.IntSliderWidget,
483 405 value=10,
484 406 )
485 407
486 408 @nt.with_setup(clear_display)
487 409 def test_call_decorated_on_trait_change():
488 410 """test calling @interact decorated functions"""
489 411 d = {}
490 412 with tt.monkeypatch(interaction, 'display', record_display):
491 413 @interact
492 414 def foo(a='default'):
493 415 d['a'] = a
494 416 return a
495 417 nt.assert_equal(len(displayed), 1)
496 418 w = displayed[0].children[0]
497 419 check_widget(w,
498 420 cls=widgets.TextWidget,
499 421 value='default',
500 422 )
501 423 # test calling the function directly
502 424 a = foo('hello')
503 425 nt.assert_equal(a, 'hello')
504 426 nt.assert_equal(d['a'], 'hello')
505 427
506 428 # test that setting trait values calls the function
507 429 w.value = 'called'
508 430 nt.assert_equal(d['a'], 'called')
509 431
510 432 @nt.with_setup(clear_display)
511 433 def test_call_decorated_kwargs_on_trait_change():
512 434 """test calling @interact(foo=bar) decorated functions"""
513 435 d = {}
514 436 with tt.monkeypatch(interaction, 'display', record_display):
515 437 @interact(a='kwarg')
516 438 def foo(a='default'):
517 439 d['a'] = a
518 440 return a
519 441 nt.assert_equal(len(displayed), 1)
520 442 w = displayed[0].children[0]
521 443 check_widget(w,
522 444 cls=widgets.TextWidget,
523 445 value='kwarg',
524 446 )
525 447 # test calling the function directly
526 448 a = foo('hello')
527 449 nt.assert_equal(a, 'hello')
528 450 nt.assert_equal(d['a'], 'hello')
529 451
530 452 # test that setting trait values calls the function
531 453 w.value = 'called'
532 454 nt.assert_equal(d['a'], 'called')
533 455
534 456 def test_fixed():
535 457 c = interactive(f, a=widgets.fixed(5), b='text')
536 458 nt.assert_equal(len(c.children), 1)
537 459 w = c.children[0]
538 460 check_widget(w,
539 461 cls=widgets.TextWidget,
540 462 value='text',
541 463 description='b',
542 464 )
543 465
544 466 def test_default_description():
545 467 c = interactive(f, b='text')
546 468 w = c.children[0]
547 469 check_widget(w,
548 470 cls=widgets.TextWidget,
549 471 value='text',
550 472 description='b',
551 473 )
552 474
553 475 def test_custom_description():
554 476 c = interactive(f, b=widgets.TextWidget(value='text', description='foo'))
555 477 w = c.children[0]
556 478 check_widget(w,
557 479 cls=widgets.TextWidget,
558 480 value='text',
559 481 description='foo',
560 482 )
483
484 def test_int_range_logic():
485 irsw = widgets.IntRangeSliderWidget
486 w = irsw(value=(2, 4), min=0, max=6)
487 check_widget(w, cls=irsw, value=(2, 4), min=0, max=6)
488 w.value = (4, 2)
489 check_widget(w, cls=irsw, value=(2, 4), min=0, max=6)
490 w.min = 3
491 check_widget(w, cls=irsw, value=(3, 4), min=3, max=6)
492 w.max = 3
493 check_widget(w, cls=irsw, value=(3, 3), min=3, max=3)
494
495 def test_float_range_logic():
496 frsw = widgets.FloatRangeSliderWidget
497 w = frsw(value=(.2, .4), min=0., max=.6)
498 check_widget(w, cls=frsw, value=(.2, .4), min=0., max=.6)
499 w.value = (.4, .2)
500 check_widget(w, cls=frsw, value=(.2, .4), min=0., max=.6)
501 w.min = .3
502 check_widget(w, cls=frsw, value=(.3, .4), min=.3, max=.6)
503 w.max = .3
504 check_widget(w, cls=frsw, value=(.3, .3), min=.3, max=.3)
General Comments 0
You need to be logged in to leave comments. Login now