holoviz / panel
1 7
import os
2

3 7
import param
4

5 7
from bokeh.models import (
6
    Div, Slider, Select, RangeSlider as BkRangeSlider, MultiSelect,
7
    Row as BkRow, CheckboxGroup, Toggle, Button, TextInput as
8
    BkTextInput,Tabs as BkTabs, Column as BkColumn, TextInput)
9 7
from panel.pane import Pane, PaneBase, Matplotlib, Bokeh, HTML
10 7
from panel.layout import Tabs, Row
11 7
from panel.param import Param, ParamMethod, ParamFunction, JSONInit
12 7
from panel.widgets import LiteralInput, RangeSlider
13 7
from panel.tests.util import mpl_available, mpl_figure
14

15

16 7
def test_instantiate_from_class():
17

18 7
    class Test(param.Parameterized):
19

20 7
        a = param.Number()
21

22 7
    assert isinstance(Pane(Test), Param)
23

24

25 7
def test_instantiate_from_parameter():
26

27 7
    class Test(param.Parameterized):
28

29 7
        a = param.Number()
30

31 7
    assert isinstance(Pane(Test.param.a), Param)
32

33

34 7
def test_instantiate_from_parameters():
35

36 7
    class Test(param.Parameterized):
37

38 7
        a = param.Number()
39

40 7
    assert isinstance(Pane(Test.param), Param)
41

42

43 7
def test_instantiate_from_instance():
44

45 7
    class Test(param.Parameterized):
46

47 7
        a = param.Number()
48

49 7
    assert isinstance(Pane(Test()), Param)
50

51

52 7
def test_instantiate_from_parameter_on_instance():
53

54 7
    class Test(param.Parameterized):
55

56 7
        a = param.Number()
57

58 7
    assert isinstance(Pane(Test().param.a), Param)
59

60

61 7
def test_instantiate_from_parameters_on_instance():
62

63 7
    class Test(param.Parameterized):
64

65 7
        a = param.Number()
66

67 7
    assert isinstance(Pane(Test().param), Param)
68

69

70 7
def test_param_pane_repr(document, comm):
71

72 7
    class Test(param.Parameterized):
73 7
        pass
74

75 7
    assert repr(Pane(Test())) == 'Param(Test)'
76

77

78 7
def test_param_pane_repr_with_params(document, comm):
79

80 7
    class Test(param.Parameterized):
81 7
        a = param.Number()
82 7
        b = param.Number()
83

84 7
    assert repr(Pane(Test(), parameters=['a'])) == "Param(Test, parameters=['a'])"
85

86
    # With a defined name.
87 7
    test_pane = Pane(Test(), parameters=['a'], name='Another')
88 7
    assert repr(test_pane) == "Param(Test, name='Another', parameters=['a'])"
89

90

91 7
def test_get_root(document, comm):
92

93 7
    class Test(param.Parameterized):
94 7
        pass
95

96 7
    test = Test()
97 7
    test_pane = Pane(test)
98 7
    model = test_pane.get_root(document, comm=comm)
99

100 7
    assert isinstance(model, BkColumn)
101 7
    assert len(model.children) == 1
102

103 7
    div = model.children[0]
104 7
    assert isinstance(div, Div)
105 7
    assert div.text == '<b>'+test.name[:-5]+'</b>'
106

107

108 7
def test_single_param(document, comm):
109

110 7
    class Test(param.Parameterized):
111 7
        a = param.Parameter(default=0)
112

113 7
    test = Test()
114 7
    test_pane = Pane(test.param.a)
115 7
    model = test_pane.get_root(document, comm=comm)
116

117 7
    assert isinstance(model, BkColumn)
118 7
    assert len(model.children) == 1
119

120 7
    widget = model.children[0]
121 7
    assert isinstance(widget, TextInput)
122 7
    assert widget.value == '0'
123

124

125 7
def test_get_root_tabs(document, comm):
126

127 7
    class Test(param.Parameterized):
128 7
        pass
129

130 7
    test = Test()
131 7
    test_pane = Pane(test, expand_layout=Tabs)
132 7
    model = test_pane.get_root(document, comm=comm)
133

134 7
    assert isinstance(model, BkTabs)
135 7
    assert len(model.tabs) == 1
136

137 7
    box = model.tabs[0].child
138 7
    assert isinstance(box, BkColumn)
139 7
    assert len(box.children) == 0
140

141

142 7
def test_number_param(document, comm):
143 7
    class Test(param.Parameterized):
144 7
        a = param.Number(default=1.2, bounds=(0, 5))
145

146 7
    test = Test()
147 7
    test_pane = Pane(test)
148 7
    model = test_pane.get_root(document, comm=comm)
149

150 7
    slider = model.children[1]
151 7
    assert isinstance(slider, Slider)
152 7
    assert slider.value == 1.2
153 7
    assert slider.start == 0
154 7
    assert slider.end == 5
155 7
    assert slider.step == 0.1
156 7
    assert slider.disabled == False
157

158
    # Check changing param value updates widget
159 7
    test.a = 3.3
160 7
    assert slider.value == 3.3
161

162
    # Check changing param attribute updates widget
163 7
    a_param = test.param['a']
164 7
    a_param.bounds = (0.1, 5.5)
165 7
    assert slider.start == 0.1
166 7
    assert slider.end == 5.5
167

168 7
    a_param.constant = True
169 7
    assert slider.disabled == True
170

171
    # Ensure cleanup works
172 7
    test_pane._cleanup(model)
173 7
    a_param.constant = False
174 7
    a_param.bounds = (-0.1, 3.8)
175 7
    test.a = 0.5
176 7
    assert slider.value == 3.3
177 7
    assert slider.start == 0.1
178 7
    assert slider.end == 5.5
179 7
    assert slider.disabled == True
180

181

182 7
def test_boolean_param(document, comm):
183 7
    class Test(param.Parameterized):
184 7
        a = param.Boolean(default=False)
185

186 7
    test = Test()
187 7
    test_pane = Pane(test)
188 7
    model = test_pane.get_root(document, comm=comm)
189

190 7
    checkbox = model.children[1]
191 7
    assert isinstance(checkbox, CheckboxGroup)
192 7
    assert checkbox.labels == ['A']
193 7
    assert checkbox.active == []
194 7
    assert checkbox.disabled == False
195

196
    # Check changing param value updates widget
197 7
    test.a = True
198 7
    assert checkbox.active == [0]
199

200
    # Check changing param attribute updates widget
201 7
    a_param = test.param['a']
202 7
    a_param.constant = True
203 7
    assert checkbox.disabled == True
204

205
    # Ensure cleanup works
206 7
    test_pane._cleanup(model)
207 7
    a_param.constant = False
208 7
    test.a = False
209 7
    assert checkbox.active == [0]
210 7
    assert checkbox.disabled == True
211

212

213 7
def test_range_param(document, comm):
214 7
    class Test(param.Parameterized):
215 7
        a = param.Range(default=(0.1, 0.5), bounds=(0, 1.1))
216

217 7
    test = Test()
218 7
    test_pane = Pane(test)
219 7
    model = test_pane.get_root(document, comm=comm)
220

221 7
    widget = model.children[1]
222 7
    assert isinstance(widget, BkRangeSlider)
223 7
    assert widget.start == 0
224 7
    assert widget.end == 1.1
225 7
    assert widget.value == (0.1, 0.5)
226

227
    # Check changing param value updates widget
228 7
    test.a = (0.2, 0.4)
229 7
    assert widget.value == (0.2, 0.4)
230

231
    # Check changing param attribute updates widget
232 7
    a_param = test.param['a']
233 7
    a_param.bounds = (0.1, 0.6)
234 7
    assert widget.start == 0.1
235 7
    assert widget.end == 0.6
236 7
    a_param.constant = True
237 7
    assert widget.disabled == True
238

239
    # Ensure cleanup works
240 7
    test_pane._cleanup(model)
241 7
    a_param.constant = False
242 7
    a_param.bounds = (-1, 1)
243 7
    test.a = (0.05, 0.2)
244 7
    assert widget.value == (0.2, 0.4)
245 7
    assert widget.start == 0.1
246 7
    assert widget.end == 0.6
247 7
    assert widget.disabled == True
248

249

250 7
def test_integer_param(document, comm):
251 7
    class Test(param.Parameterized):
252 7
        a = param.Integer(default=2, bounds=(0, 5))
253

254 7
    test = Test()
255 7
    test_pane = Pane(test)
256 7
    model = test_pane.get_root(document, comm=comm)
257

258 7
    slider = model.children[1]
259 7
    assert isinstance(slider, Slider)
260 7
    assert slider.value == 2
261 7
    assert slider.start == 0
262 7
    assert slider.end == 5
263 7
    assert slider.step == 1
264 7
    assert slider.disabled == False
265

266
    # Check changing param value updates widget
267 7
    test.a = 3
268 7
    assert slider.value == 3
269

270
    # Check changing param attribute updates widget
271 7
    a_param = test.param['a']
272 7
    a_param.bounds = (1, 6)
273 7
    assert slider.start == 1
274 7
    assert slider.end == 6
275

276 7
    a_param.constant = True
277 7
    assert slider.disabled == True
278

279
    # Ensure cleanup works
280 7
    test_pane._cleanup(model)
281 7
    a_param.constant = False
282 7
    a_param.bounds = (-1, 7)
283 7
    test.a = 1
284 7
    assert slider.value == 3
285 7
    assert slider.start == 1
286 7
    assert slider.end == 6
287 7
    assert slider.disabled == True
288

289

290 7
def test_object_selector_param(document, comm):
291 7
    class Test(param.Parameterized):
292 7
        a = param.ObjectSelector(default='b', objects=[1, 'b', 'c'])
293

294 7
    test = Test()
295 7
    test_pane = Pane(test)
296 7
    model = test_pane.get_root(document, comm=comm)
297

298 7
    select = model.children[1]
299 7
    assert isinstance(select, Select)
300 7
    assert select.options == [('1','1'), ('b','b'), ('c','c')]
301 7
    assert select.value == 'b'
302 7
    assert select.disabled == False
303

304
    # Check changing param value updates widget
305 7
    test.a = 1
306 7
    assert select.value == '1'
307

308
    # Check changing param attribute updates widget
309 7
    a_param = test.param['a']
310 7
    a_param.objects = ['c', 'd', 1]
311 7
    assert select.options == [('c','c'), ('d','d'), ('1','1')]
312

313 7
    a_param.constant = True
314 7
    assert select.disabled == True
315

316
    # Ensure cleanup works
317 7
    test_pane._cleanup(model)
318 7
    a_param.constant = False
319 7
    a_param.objects = [1, 'c', 'd']
320 7
    test.a = 'd'
321 7
    assert select.value == '1'
322 7
    assert select.options == [('c','c'), ('d','d'), ('1','1')]
323 7
    assert select.disabled == True
324

325

326 7
def test_list_selector_param(document, comm):
327 7
    class Test(param.Parameterized):
328 7
        a = param.ListSelector(default=['b', 1], objects=[1, 'b', 'c'])
329

330 7
    test = Test()
331 7
    test_pane = Pane(test)
332 7
    model = test_pane.get_root(document, comm=comm)
333

334 7
    slider = model.children[1]
335 7
    assert isinstance(slider, MultiSelect)
336 7
    assert slider.options == ['1', 'b', 'c']
337 7
    assert slider.value == ['b', '1']
338 7
    assert slider.disabled == False
339

340
    # Check changing param value updates widget
341 7
    test.a = ['c', 1]
342 7
    assert slider.value == ['c', '1']
343

344
    # Check changing param attribute updates widget
345 7
    a_param = test.param['a']
346 7
    a_param.objects = ['c', 'd', 1]
347 7
    assert slider.options == ['c', 'd', '1']
348

349 7
    a_param.constant = True
350 7
    assert slider.disabled == True
351

352
    # Ensure cleanup works
353 7
    test_pane._cleanup(model)
354 7
    a_param.constant = False
355 7
    a_param.objects = [1, 'c', 'd']
356 7
    test.a = ['d']
357 7
    assert slider.value == ['c', '1']
358 7
    assert slider.options == ['c', 'd', '1']
359 7
    assert slider.disabled == True
360

361

362 7
def test_action_param(document, comm):
363 7
    class Test(param.Parameterized):
364 7
        a = param.Action(lambda x: setattr(x, 'b', 2))
365 7
        b = param.Number(default=1)
366

367 7
    test = Test()
368 7
    test_pane = Pane(test)
369 7
    model = test_pane.get_root(document, comm=comm)
370

371 7
    button = model.children[1]
372 7
    assert isinstance(button, Button)
373

374
    # Check that the action is actually executed
375 7
    pn_button = test_pane.layout[1]
376 7
    pn_button.clicks = 1
377

378 7
    assert test.b == 2
379

380

381 7
def test_explicit_params(document, comm):
382 7
    class Test(param.Parameterized):
383 7
        a = param.Boolean(default=False)
384 7
        b = param.Integer(default=1)
385

386 7
    test = Test()
387 7
    test_pane = Pane(test, parameters=['a'])
388 7
    model = test_pane.get_root(document, comm=comm)
389

390 7
    assert len(model.children) == 2
391 7
    assert isinstance(model.children[1], CheckboxGroup)
392

393

394 7
def test_param_precedence(document, comm):
395 7
    class Test(param.Parameterized):
396 7
        a = param.Number(default=1.2, bounds=(0, 5))
397

398 7
    test = Test()
399 7
    test_pane = Pane(test)
400

401
    # Check changing precedence attribute hides and shows widget
402 7
    a_param = test.param['a']
403 7
    a_param.precedence = -1
404 7
    assert test_pane._widgets['a'] not in test_pane._widget_box.objects
405

406 7
    a_param.precedence = 1
407 7
    assert test_pane._widgets['a'] in test_pane._widget_box.objects
408

409 7
    a_param.precedence = None
410 7
    assert test_pane._widgets['a'] in test_pane._widget_box.objects
411

412

413 7
def test_param_label(document, comm):
414 7
    class Test(param.Parameterized):
415 7
        a = param.Number(default=1.2, bounds=(0, 5), label='A')
416 7
        b = param.Action(label='B')
417

418 7
    test = Test()
419 7
    test_pane = Pane(test)
420

421
    # Check updating label changes widget name
422 7
    a_param = test.param['a']
423 7
    a_param.label = 'B'
424 7
    assert test_pane._widgets['a'].name == 'B'
425

426 7
    b_param = test.param['b']
427 7
    b_param.label = 'C'
428 7
    assert test_pane._widgets['b'].name == 'C'
429

430

431 7
def test_param_precedence_ordering(document, comm):
432 7
    class Test(param.Parameterized):
433 7
        a = param.Number(default=1.2, bounds=(0, 5), precedence=-1)
434 7
        b = param.Boolean(default=True, precedence=1)
435

436 7
    test = Test()
437 7
    test_pane = Pane(test)
438

439
    # Check changing precedence attribute hides and shows widget
440 7
    a_param = test.param['a']
441 7
    a_param.precedence = 2
442 7
    assert test_pane._widget_box.objects == [test_pane._widgets[w] for w in ('_title', 'b', 'a')]
443

444 7
    a_param.precedence = 1
445 7
    assert test_pane._widget_box.objects == [test_pane._widgets[w] for w in ('_title', 'a', 'b')]
446

447

448 7
def test_param_step(document, comm):
449 7
    class Test(param.Parameterized):
450 7
        a = param.Number(default=1.2, bounds=(0, 5), step=0.1)
451

452 7
    test = Test()
453 7
    test_pane = Pane(test)
454 7
    assert test_pane._widgets['a'].step == 0.1
455

456 7
    a_param = test.param['a']
457 7
    a_param.step = 0.25
458 7
    assert test_pane._widgets['a'].step == 0.25
459

460

461 7
def test_replace_param_object(document, comm):
462 7
    class Test(param.Parameterized):
463 7
        a = param.Number(bounds=(0, 10))
464

465 7
    pane = Param()
466

467 7
    model = pane.get_root(document, comm=comm)
468

469 7
    assert model.children == []
470

471 7
    pane.object = Test()
472

473 7
    assert len(model.children) == 2
474 7
    title, widget = model.children
475

476 7
    assert isinstance(title, Div)
477 7
    assert title.text == '<b>Test</b>'
478

479 7
    assert isinstance(widget, Slider)
480 7
    assert widget.start == 0
481 7
    assert widget.end == 10
482

483
    # Check when object is from parameters
484 7
    pane.object = Test().param
485

486 7
    assert len(model.children) == 2
487 7
    title, widget = model.children
488

489 7
    assert isinstance(title, Div)
490 7
    assert title.text == '<b>Test</b>'
491

492 7
    assert isinstance(widget, Slider)
493 7
    assert widget.start == 0
494 7
    assert widget.end == 10
495

496
    # Check when object is None
497 7
    pane.object = None
498

499 7
    assert len(model.children) == 0
500

501

502 7
def test_set_name(document, comm):
503 7
    class Test(param.Parameterized):
504 7
        a = param.Number(bounds=(0, 10))
505 7
        b = param.String(default='A')
506

507 7
    pane = Param(Test(), name='First')
508

509 7
    model = pane.get_root(document, comm=comm)
510

511 7
    assert len(model.children) == 3
512 7
    title, slider, text = model.children
513 7
    assert isinstance(title, Div)
514
    # Check setting name displays in as a title
515 7
    assert title.text == '<b>First</b>'
516 7
    assert isinstance(slider, Slider)
517 7
    assert isinstance(text, TextInput)
518

519 7
    pane.name = 'Second'
520

521 7
    assert len(model.children) == 3
522 7
    title, _, _ = model.children
523 7
    assert isinstance(title, Div)
524
    # Check the title updates with name
525 7
    assert title.text == '<b>Second</b>'
526

527

528 7
def test_set_parameters(document, comm):
529 7
    class Test(param.Parameterized):
530 7
        a = param.Number(bounds=(0, 10))
531 7
        b = param.String(default='A')
532

533 7
    pane = Param(Test())
534

535 7
    model = pane.get_root(document, comm=comm)
536

537 7
    assert len(model.children) == 3
538 7
    title, slider, text = model.children
539 7
    assert isinstance(title, Div)
540 7
    assert isinstance(slider, Slider)
541 7
    assert isinstance(text, TextInput)
542

543 7
    pane.parameters = ['b']
544

545 7
    assert len(model.children) == 2
546 7
    title, text = model.children
547 7
    assert isinstance(title, Div)
548 7
    assert isinstance(text, TextInput)
549

550

551 7
def test_trigger_parameters(document, comm):
552 7
    class Test(param.Parameterized):
553 7
        a = param.ListSelector(objects=[1,2,3,4], default=list())
554

555 7
    t = Test()
556 7
    t.a.append(4)
557

558 7
    pane = Param(t.param.a)
559

560 7
    t.a.append(1)
561 7
    t.param.trigger('a')
562

563 7
    assert pane[0].value == [4, 1]
564

565

566 7
def test_set_display_threshold(document, comm):
567 7
    class Test(param.Parameterized):
568 7
        a = param.Number(bounds=(0, 10), precedence=1)
569 7
        b = param.String(default='A', precedence=2)
570

571 7
    pane = Param(Test())
572

573 7
    model = pane.get_root(document, comm=comm)
574

575 7
    assert len(model.children) == 3
576 7
    title, slider, text = model.children
577 7
    assert isinstance(title, Div)
578 7
    assert isinstance(slider, Slider)
579 7
    assert isinstance(text, TextInput)
580

581 7
    pane.display_threshold = 1.5
582

583 7
    assert len(model.children) == 2
584 7
    title, text = model.children
585 7
    assert isinstance(title, Div)
586 7
    assert isinstance(text, TextInput)
587

588

589 7
def test_set_widgets(document, comm):
590 7
    class Test(param.Parameterized):
591 7
        a = param.Number(default=1, bounds=(0, 10), precedence=1)
592 7
        b = param.String(default='A', precedence=2)
593

594 7
    pane = Param(Test())
595

596 7
    model = pane.get_root(document, comm=comm)
597

598 7
    assert len(model.children) == 3
599 7
    title, slider, text = model.children
600 7
    assert isinstance(title, Div)
601 7
    assert isinstance(slider, Slider)
602 7
    assert isinstance(text, TextInput)
603

604 7
    pane.widgets = {'a': LiteralInput(value=1, type=(float, int))}
605

606 7
    assert len(model.children) == 3
607 7
    title, number, text = model.children
608 7
    assert isinstance(title, Div)
609 7
    assert isinstance(number, TextInput)
610 7
    assert isinstance(text, TextInput)
611

612 7
    pane.widgets = {'a': {'height':100}}
613

614 7
    assert len(model.children) == 3
615 7
    title, number, text = model.children
616 7
    assert isinstance(title, Div)
617 7
    assert isinstance(number, Slider)
618 7
    assert number.height == 100
619 7
    assert isinstance(text, TextInput)
620

621 7
    pane.widgets = {'a': {'type': LiteralInput, 'height':100}}
622

623 7
    assert len(model.children) == 3
624 7
    title, number, text = model.children
625 7
    assert isinstance(title, Div)
626 7
    assert isinstance(number, TextInput)
627 7
    assert number.height == 100
628 7
    assert isinstance(text, TextInput)
629

630

631 7
def test_set_widgets_throttled(document, comm):
632 7
    class Test(param.Parameterized):
633 7
        a = param.Number(default=0, bounds=(0, 10), precedence=1)
634

635 7
    test = Test()
636 7
    pane = Param(test)
637 7
    model = pane.get_root(document, comm=comm)
638

639 7
    pane.widgets = {"a": {"throttled": False}}
640 7
    assert len(model.children) == 2
641 7
    _, number = model.children
642

643 7
    number.value = 1
644 7
    assert number.value == 1
645 7
    assert number.value_throttled != 1
646 7
    assert test.a == 1
647

648 7
    test.a = 2
649 7
    assert number.value == 2
650 7
    assert number.value_throttled != 2
651 7
    assert test.a == 2
652

653
    # By setting throttled to true,
654
    # `test.a` is linked to `number.value_throttled`
655
    # instead of `number.value`.
656 7
    pane.widgets = {"a": {"throttled": True}}
657 7
    assert len(model.children) == 2
658 7
    _, number = model.children
659

660 7
    pane._widgets['a']._process_events({'value_throttled': 3})
661 7
    assert number.value != 3
662 7
    assert test.a == 3
663

664 7
    pane._widgets['a']._process_events({'value': 4})
665 7
    assert test.a == 3
666 7
    assert number.value == 4
667

668

669 7
def test_set_show_name(document, comm):
670 7
    class Test(param.Parameterized):
671 7
        a = param.Number(bounds=(0, 10))
672

673 7
    pane = Param(Test())
674

675 7
    model = pane.get_root(document, comm=comm)
676

677 7
    assert len(model.children) == 2
678 7
    title, widget = model.children
679 7
    assert isinstance(title, Div)
680 7
    assert isinstance(widget, Slider)
681

682 7
    pane.show_name = False
683

684 7
    assert len(model.children) == 1
685 7
    assert isinstance(model.children[0], Slider)
686

687

688 7
def test_set_show_labels(document, comm):
689 7
    class Test(param.Parameterized):
690 7
        a = param.Number(bounds=(0, 10))
691

692 7
    pane = Param(Test())
693

694 7
    model = pane.get_root(document, comm=comm)
695

696 7
    assert len(model.children) == 2
697 7
    title, widget = model.children
698 7
    assert isinstance(title, Div)
699 7
    assert isinstance(widget, Slider)
700 7
    assert widget.title == 'A'
701

702 7
    pane.show_labels = False
703

704 7
    assert len(model.children) == 2
705 7
    assert isinstance(model.children[1], Slider)
706 7
    assert model.children[1].title == ''
707

708

709 7
def test_expand_param_subobject(document, comm):
710 7
    class Test(param.Parameterized):
711 7
        a = param.Parameter()
712

713 7
    test = Test(a=Test(name='Nested'))
714 7
    test_pane = Pane(test)
715 7
    model = test_pane.get_root(document, comm=comm)
716

717 7
    toggle = model.children[1].children[1]
718 7
    assert isinstance(toggle, Toggle)
719

720
    # Expand subpane
721 7
    test_pane._widgets['a'][1].value = True
722 7
    assert len(model.children) == 3
723 7
    _, _, subpanel = test_pane.layout.objects
724 7
    col = model.children[2]
725 7
    assert isinstance(col, BkColumn)
726 7
    assert isinstance(col, BkColumn)
727 7
    assert len(col.children) == 2
728 7
    div, widget = col.children
729 7
    assert div.text == '<b>Nested</b>'
730 7
    assert isinstance(widget, BkTextInput)
731

732
    # Collapse subpanel
733 7
    test_pane._widgets['a'][1].value = False
734 7
    assert len(model.children) == 2
735

736

737 7
def test_switch_param_subobject(document, comm):
738 7
    class Test(param.Parameterized):
739 7
        a = param.ObjectSelector()
740

741 7
    o1 = Test(name='Subobject 1')
742 7
    o2 = Test(name='Subobject 2')
743 7
    Test.param['a'].objects = [o1, o2, 3]
744 7
    test = Test(a=o1, name='Nested')
745 7
    test_pane = Pane(test)
746 7
    model = test_pane.get_root(document, comm=comm)
747

748 7
    toggle = model.children[1].children[1]
749 7
    assert isinstance(toggle, Toggle)
750

751
    # Expand subpane
752 7
    test_pane._widgets['a'][1].value = True
753 7
    assert len(model.children) == 3
754 7
    _, _, subpanel = test_pane.layout.objects
755 7
    col = model.children[2]
756 7
    assert isinstance(col, BkColumn)
757 7
    assert len(col.children) == 2
758 7
    div, row = col.children
759 7
    assert div.text == '<b>Subobject 1</b>'
760 7
    assert isinstance(row.children[0], Select)
761

762
    # Switch subobject
763 7
    test_pane._widgets['a'][0].value = o2
764 7
    _, _, subpanel = test_pane.layout.objects
765 7
    col = model.children[2]
766 7
    assert isinstance(col, BkColumn)
767 7
    assert len(col.children) == 2
768 7
    div, row = col.children
769 7
    assert div.text == '<b>Subobject 2</b>'
770 7
    assert isinstance(row.children[0], Select)
771

772
    # Collapse subpanel
773 7
    test_pane._widgets['a'][1].value = False
774 7
    assert len(model.children) == 2
775 7
    assert subpanel._models == {}
776

777

778

779 7
def test_expand_param_subobject_into_row(document, comm):
780 7
    class Test(param.Parameterized):
781 7
        a = param.Parameter()
782

783 7
    test = Test(a=Test(name='Nested'))
784 7
    row = Row()
785 7
    test_pane = Pane(test, expand_layout=row)
786 7
    layout = Row(test_pane, row)
787 7
    model = layout.get_root(document, comm=comm)
788

789 7
    toggle = model.children[0].children[1].children[1]
790 7
    assert isinstance(toggle, Toggle)
791

792
    # Expand subpane
793 7
    test_pane._widgets['a'][1].value = True
794 7
    assert len(model.children) == 2
795 7
    subpanel = row.objects[0]
796 7
    row = model.children[1]
797 7
    assert isinstance(row, BkRow)
798 7
    assert len(row.children) == 1
799 7
    box = row.children[0]
800 7
    assert isinstance(box, BkColumn)
801 7
    assert len(box.children) == 2
802 7
    div, widget = box.children
803 7
    assert div.text == '<b>Nested</b>'
804 7
    assert isinstance(widget, BkTextInput)
805

806
    # Collapse subpanel
807 7
    test_pane._widgets['a'][1].value = False
808 7
    assert len(row.children) == 0
809 7
    assert subpanel._models == {}
810

811

812 7
def test_expand_param_subobject_expand(document, comm):
813 7
    class Test(param.Parameterized):
814 7
        a = param.Parameter()
815

816 7
    test = Test(a=Test(name='Nested'))
817 7
    test_pane = Pane(test, expand=True, expand_button=True)
818 7
    model = test_pane.get_root(document, comm=comm)
819

820 7
    toggle = model.children[1].children[1]
821 7
    assert isinstance(toggle, Toggle)
822

823
    # Expand subpane
824 7
    assert len(model.children) == 3
825 7
    _, _, subpanel = test_pane.layout.objects
826 7
    col = model.children[2]
827 7
    assert isinstance(col, BkColumn)
828 7
    assert len(col.children) == 2
829 7
    div, widget = col.children
830 7
    assert div.text == '<b>Nested</b>'
831 7
    assert isinstance(widget, BkTextInput)
832

833
    # Collapse subpanel
834 7
    test_pane._widgets['a'][1].value = False
835 7
    assert len(model.children) == 2
836 7
    assert subpanel._models == {}
837

838

839 7
def test_param_subobject_expand_no_toggle(document, comm):
840 7
    class Test(param.Parameterized):
841 7
        a = param.Parameter()
842

843 7
    test = Test(a=Test(name='Nested'))
844 7
    test_pane = Pane(test, expand=True,
845
                     expand_button=False)
846 7
    model = test_pane.get_root(document, comm=comm)
847

848
    # Assert no toggle was added
849 7
    assert len(model.children) == 3
850

851
    # Expand subpane
852 7
    _, _, subpanel = test_pane.layout.objects
853 7
    div, widget = model.children[2].children
854 7
    assert div.text == '<b>Nested</b>'
855 7
    assert isinstance(widget, BkTextInput)
856

857

858 7
def test_expand_param_subobject_tabs(document, comm):
859 7
    class Test(param.Parameterized):
860 7
        abc = param.Parameter()
861

862 7
    test = Test(abc=Test(name='Nested'), name='A')
863 7
    test_pane = Pane(test, expand_layout=Tabs)
864 7
    model = test_pane.get_root(document, comm=comm)
865

866 7
    toggle = model.tabs[0].child.children[0].children[1]
867 7
    assert isinstance(toggle, Toggle)
868

869
    # Expand subpanel
870 7
    test_pane._widgets['abc'][1].value = True
871 7
    assert len(model.tabs) == 2
872 7
    _, subpanel = test_pane.layout.objects
873 7
    subtabs = model.tabs[1].child
874 7
    assert model.tabs[1].title == 'Abc'
875 7
    assert isinstance(subtabs, BkTabs)
876 7
    assert len(subtabs.tabs) == 1
877 7
    assert subtabs.tabs[0].title == 'Nested'
878

879 7
    box = subtabs.tabs[0].child
880 7
    assert isinstance(box, BkColumn)
881 7
    assert len(box.children) == 1
882 7
    widget = box.children[0]
883 7
    assert isinstance(widget, BkTextInput)
884

885
    # Collapse subpanel
886 7
    test_pane._widgets['abc'][1].value = False
887 7
    assert len(model.tabs) == 1
888

889

890 7
def test_param_js_callbacks(document, comm):
891 7
    class JsButton(param.Parameterized):
892 7
        param_btn = param.Action(lambda self: print('Action Python Response'), label='Action')
893

894 7
    param_button = Param(JsButton())
895 7
    code = "console.log('Action button clicked')"
896 7
    param_button[1].js_on_click(code=code)
897

898 7
    model = param_button.get_root(document, comm=comm)
899

900 7
    button = model.children[1]
901 7
    assert len(button.js_event_callbacks) == 1
902 7
    callbacks = button.js_event_callbacks
903 7
    assert 'button_click' in callbacks
904 7
    assert len(callbacks['button_click']) == 1
905 7
    assert code in callbacks['button_click'][0].code
906

907

908 7
class View(param.Parameterized):
909

910 7
    a = param.Integer(default=0)
911

912 7
    b = param.Parameter()
913

914 7
    @param.depends('a')
915 2
    def view(self):
916 7
        return Div(text='%d' % self.a)
917

918 7
    @param.depends('b.param')
919 2
    def subobject_view(self):
920 7
        return Div(text='%d' % self.b.a)
921

922 7
    @param.depends('a')
923 2
    def mpl_view(self):
924 7
        return mpl_figure()
925

926 7
    @param.depends('a')
927 2
    def mixed_view(self):
928 7
        return self.view() if (self.a % 2) else self.mpl_view()
929

930

931 7
def test_get_param_function_pane_type():
932 7
    test = View()
933

934 7
    def view(a):
935 0
        return Div(text='%d' % a)
936

937 7
    assert PaneBase.get_pane_type(view) is not ParamFunction
938 7
    assert PaneBase.get_pane_type(param.depends(test.param.a)(view)) is ParamFunction
939

940

941 7
def test_param_function_pane(document, comm):
942 7
    test = View()
943

944 7
    @param.depends(test.param.a)
945 2
    def view(a):
946 7
        return Div(text='%d' % a)
947

948 7
    pane = Pane(view)
949 7
    inner_pane = pane._pane
950 7
    assert isinstance(inner_pane, Bokeh)
951

952
    # Create pane
953 7
    row = pane.get_root(document, comm=comm)
954 7
    assert isinstance(row, BkRow)
955 7
    assert len(row.children) == 1
956 7
    model = row.children[0]
957 7
    assert pane._models[row.ref['id']][0] is row
958 7
    assert isinstance(model, Div)
959 7
    assert model.text == '0'
960

961
    # Update pane
962 7
    test.a = 5
963 7
    new_model = row.children[0]
964 7
    assert inner_pane is pane._pane
965 7
    assert new_model.text == '5'
966 7
    assert pane._models[row.ref['id']][0] is row
967

968
    # Cleanup pane
969 7
    pane._cleanup(row)
970 7
    assert pane._models == {}
971 7
    assert inner_pane._models == {}
972

973

974 7
def test_param_function_pane_update(document, comm):
975 7
    test = View()
976

977 7
    objs = {
978
        0: HTML("012"),
979
        1: HTML("123")
980
    }
981

982 7
    @param.depends(test.param.a)
983 2
    def view(a):
984 7
        return objs[a]
985

986 7
    pane = Pane(view)
987 7
    inner_pane = pane._pane
988 7
    assert inner_pane is not objs[0]
989 7
    assert inner_pane.object is objs[0].object
990 7
    assert pane._internal
991

992 7
    test.a = 1
993

994 7
    assert pane._pane is inner_pane
995 7
    assert pane._internal
996

997 7
    objs[0].param.watch(print, ['object'])
998

999 7
    test.a = 0
1000

1001 7
    assert pane._pane is not inner_pane
1002 7
    assert not pane._internal
1003

1004

1005 7
def test_get_param_method_pane_type():
1006 7
    assert PaneBase.get_pane_type(View().view) is ParamMethod
1007

1008

1009 7
def test_param_method_pane(document, comm):
1010 7
    test = View()
1011 7
    pane = Pane(test.view)
1012 7
    inner_pane = pane._pane
1013 7
    assert isinstance(inner_pane, Bokeh)
1014

1015
    # Create pane
1016 7
    row = pane.get_root(document, comm=comm)
1017 7
    assert isinstance(row, BkRow)
1018 7
    assert len(row.children) == 1
1019 7
    model = row.children[0]
1020 7
    assert pane._models[row.ref['id']][0] is row
1021 7
    assert isinstance(model, Div)
1022 7
    assert model.text == '0'
1023

1024
    # Update pane
1025 7
    test.a = 5
1026 7
    new_model = row.children[0]
1027 7
    assert inner_pane is pane._pane
1028 7
    assert new_model.text == '5'
1029 7
    assert pane._models[row.ref['id']][0] is row
1030

1031
    # Cleanup pane
1032 7
    pane._cleanup(row)
1033 7
    assert pane._models == {}
1034 7
    assert inner_pane._models == {}
1035

1036

1037 7
def test_param_method_pane_subobject(document, comm):
1038 7
    subobject = View(name='Nested', a=42)
1039 7
    test = View(b=subobject)
1040 7
    pane = Pane(test.subobject_view)
1041 7
    inner_pane = pane._pane
1042 7
    assert isinstance(inner_pane, Bokeh)
1043

1044
    # Create pane
1045 7
    row = pane.get_root(document, comm=comm)
1046 7
    assert isinstance(row, BkRow)
1047 7
    assert len(row.children) == 1
1048 7
    model = row.children[0]
1049 7
    assert isinstance(model, Div)
1050 7
    assert model.text == '42'
1051

1052
    # Ensure that subobject is being watched
1053 7
    watchers = pane._callbacks
1054 7
    assert any(w.inst is subobject for w in watchers)
1055 7
    assert pane._models[row.ref['id']][0] is row
1056

1057
    # Ensure that switching the subobject triggers update in watchers
1058 7
    new_subobject = View(name='Nested', a=42)
1059 7
    test.b = new_subobject
1060 7
    assert pane._models[row.ref['id']][0] is row
1061 7
    watchers = pane._callbacks
1062 7
    assert not any(w.inst is subobject for w in watchers)
1063 7
    assert any(w.inst is new_subobject for w in watchers)
1064

1065
    # Cleanup pane
1066 7
    pane._cleanup(row)
1067 7
    assert pane._models == {}
1068 7
    assert inner_pane._models == {}
1069

1070

1071 7
@mpl_available
1072 2
def test_param_method_pane_mpl(document, comm):
1073 7
    test = View()
1074 7
    pane = Pane(test.mpl_view)
1075 7
    inner_pane = pane._pane
1076 7
    assert isinstance(inner_pane, Matplotlib)
1077

1078
    # Create pane
1079 7
    row = pane.get_root(document, comm=comm)
1080 7
    assert isinstance(row, BkRow)
1081 7
    assert len(row.children) == 1
1082 7
    model = row.children[0]
1083 7
    assert pane._models[row.ref['id']][0] is row
1084 7
    text = model.text
1085

1086
    # Update pane
1087 7
    test.a = 5
1088 7
    new_model = row.children[0]
1089 7
    assert inner_pane is pane._pane
1090 7
    assert new_model is model
1091 7
    assert new_model.text != text
1092 7
    assert pane._models[row.ref['id']][0] is row
1093

1094
    # Cleanup pane
1095 7
    pane._cleanup(row)
1096 7
    assert pane._models == {}
1097 7
    assert inner_pane._models == {}
1098

1099

1100 7
@mpl_available
1101 2
def test_param_method_pane_changing_type(document, comm):
1102 7
    test = View()
1103 7
    pane = Pane(test.mixed_view)
1104 7
    inner_pane = pane._pane
1105 7
    assert isinstance(inner_pane, Matplotlib)
1106

1107
    # Create pane
1108 7
    row = pane.get_root(document, comm=comm)
1109 7
    assert isinstance(row, BkRow)
1110 7
    assert len(row.children) == 1
1111 7
    model = row.children[0]
1112 7
    text = model.text
1113 7
    assert text.startswith('&lt;img src=')
1114

1115
    # Update pane
1116 7
    test.a = 5
1117 7
    new_model = row.children[0]
1118 7
    new_pane = pane._pane
1119 7
    assert isinstance(new_pane, Bokeh)
1120 7
    assert isinstance(new_model, Div)
1121 7
    assert new_model.text != text
1122

1123
    # Cleanup pane
1124 7
    new_pane._cleanup(row)
1125 7
    assert new_pane._models == {}
1126

1127

1128 7
def test_jsoninit_class_from_env_var():
1129 7
    os.environ['PARAM_JSON_INIT'] = '{"a": 1}'
1130

1131 7
    json_init = JSONInit()
1132

1133 7
    class Test(param.Parameterized):
1134 7
        a = param.Integer()
1135

1136 7
    json_init(Test)
1137

1138 7
    assert Test.a == 1
1139 7
    del os.environ['PARAM_JSON_INIT']
1140

1141

1142 7
def test_jsoninit_instance_from_env_var():
1143 7
    os.environ['PARAM_JSON_INIT'] = '{"a": 2}'
1144

1145 7
    json_init = JSONInit()
1146

1147 7
    class Test(param.Parameterized):
1148 7
        a = param.Integer()
1149

1150 7
    test = Test()
1151 7
    json_init(test)
1152

1153 7
    assert test.a == 2
1154 7
    del os.environ['PARAM_JSON_INIT']
1155

1156 7
def test_change_object_and_keep_parameters():
1157
    """Test that https://github.com/holoviz/panel/issues/1581 is solved"""
1158
    # Given
1159 7
    class TextModel(param.Parameterized):
1160 7
        text = param.String()
1161 7
        param2 = param.String()
1162

1163 7
    class TextView(param.Parameterized):
1164 7
        text = param.ClassSelector(class_=TextModel)
1165 7
        text_pane = param.Parameter()
1166

1167 7
        def __init__(self, **params):
1168 7
            params["text"] = TextModel(text="Original Text")
1169 7
            super().__init__(**params)
1170

1171 7
            self.text_pane = Param(
1172
                self.text, parameters=["text"]
1173
            )
1174

1175 7
        @param.depends("text", watch=True)
1176 2
        def _update_text_pane(self, *_):
1177 7
            self.text_pane.object = self.text
1178

1179 7
    view = TextView()
1180 7
    assert view.text_pane.parameters==["text"]
1181

1182
    # When
1183 7
    view.text = TextModel(text="New TextModel")
1184
    # Then
1185 7
    assert view.text_pane.parameters==["text"]
1186

1187

1188 7
def test_rerender_bounded_widget_when_bounds_set_and_unset():
1189 7
    class Test(param.Parameterized):
1190 7
        num = param.Range()
1191

1192 7
    test = Test()
1193 7
    p = Param(test)
1194

1195 7
    assert isinstance(p._widgets['num'], LiteralInput)
1196 7
    assert p._widgets['num'] in p._widget_box
1197

1198 7
    test.param.num.bounds = (0, 5)
1199

1200 7
    assert isinstance(p._widgets['num'], RangeSlider)
1201 7
    assert p._widgets['num'] in p._widget_box
1202

1203 7
    test.param.num.bounds = (None, 5)
1204

1205 7
    assert isinstance(p._widgets['num'], LiteralInput)
1206 7
    assert p._widgets['num'] in p._widget_box
1207

Read our documentation on viewing source code .

Loading