1 7
from __future__ import print_function
2

3 7
import os
4

5 7
import param
6

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

17

18 7
def test_instantiate_from_class():
19

20 7
    class Test(param.Parameterized):
21

22 7
        a = param.Number()
23

24 7
    assert isinstance(Pane(Test), Param)
25

26

27 7
def test_instantiate_from_parameter():
28

29 7
    class Test(param.Parameterized):
30

31 7
        a = param.Number()
32

33 7
    assert isinstance(Pane(Test.param.a), Param)
34

35

36 7
def test_instantiate_from_parameters():
37

38 7
    class Test(param.Parameterized):
39

40 7
        a = param.Number()
41

42 7
    assert isinstance(Pane(Test.param), Param)
43

44

45 7
def test_instantiate_from_instance():
46

47 7
    class Test(param.Parameterized):
48

49 7
        a = param.Number()
50

51 7
    assert isinstance(Pane(Test()), Param)
52

53

54 7
def test_instantiate_from_parameter_on_instance():
55

56 7
    class Test(param.Parameterized):
57

58 7
        a = param.Number()
59

60 7
    assert isinstance(Pane(Test().param.a), Param)
61

62

63 7
def test_instantiate_from_parameters_on_instance():
64

65 7
    class Test(param.Parameterized):
66

67 7
        a = param.Number()
68

69 7
    assert isinstance(Pane(Test().param), Param)
70

71

72 7
def test_param_pane_repr(document, comm):
73

74 7
    class Test(param.Parameterized):
75 7
        pass
76

77 7
    assert repr(Pane(Test())) == 'Param(Test)'
78

79

80 7
def test_param_pane_repr_with_params(document, comm):
81

82 7
    class Test(param.Parameterized):
83 7
        a = param.Number()
84 7
        b = param.Number()
85

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

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

92

93 7
def test_get_root(document, comm):
94

95 7
    class Test(param.Parameterized):
96 7
        pass
97

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

102 7
    assert isinstance(model, BkColumn)
103 7
    assert len(model.children) == 1
104

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

109

110 7
def test_single_param(document, comm):
111

112 7
    class Test(param.Parameterized):
113 7
        a = param.Parameter(default=0)
114

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

119 7
    assert isinstance(model, BkColumn)
120 7
    assert len(model.children) == 1
121

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

126

127 7
def test_get_root_tabs(document, comm):
128

129 7
    class Test(param.Parameterized):
130 7
        pass
131

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

136 7
    assert isinstance(model, BkTabs)
137 7
    assert len(model.tabs) == 1
138

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

143

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

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

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

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

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

170 7
    a_param.constant = True
171 7
    assert slider.disabled == True
172

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

183

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

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

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

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

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

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

214

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

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

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

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

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

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

251

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

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

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

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

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

278 7
    a_param.constant = True
279 7
    assert slider.disabled == True
280

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

291

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

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

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

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

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

315 7
    a_param.constant = True
316 7
    assert select.disabled == True
317

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

327

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

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

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

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

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

351 7
    a_param.constant = True
352 7
    assert slider.disabled == True
353

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

363

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

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

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

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

380 7
    assert test.b == 2
381

382

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

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

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

395

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

400 7
    test = Test()
401 7
    test_pane = Pane(test)
402

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

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

411

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

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

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

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

429

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

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

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

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

446

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

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

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

459

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

464 7
    pane = Param()
465

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

468 7
    assert model.children == []
469

470 7
    pane.object = Test()
471

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

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

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

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

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

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

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

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

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

500

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

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

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

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

518 7
    pane.name = 'Second'
519

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

526

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

532 7
    pane = Param(Test())
533

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

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

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

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

549

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

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

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

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

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

564

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

570 7
    pane = Param(Test())
571

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

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

580 7
    pane.display_threshold = 1.5
581

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

587

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

593 7
    pane = Param(Test())
594

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

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

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

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

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

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

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

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

629 7
def test_set_show_name(document, comm):
630 7
    class Test(param.Parameterized):
631 7
        a = param.Number(bounds=(0, 10))
632

633 7
    pane = Param(Test())
634

635 7
    model = pane.get_root(document, comm=comm)
636

637 7
    assert len(model.children) == 2
638 7
    title, widget = model.children
639 7
    assert isinstance(title, Div)
640 7
    assert isinstance(widget, Slider)
641

642 7
    pane.show_name = False
643

644 7
    assert len(model.children) == 1
645 7
    assert isinstance(model.children[0], Slider)
646

647

648 7
def test_set_show_labels(document, comm):
649 7
    class Test(param.Parameterized):
650 7
        a = param.Number(bounds=(0, 10))
651

652 7
    pane = Param(Test())
653

654 7
    model = pane.get_root(document, comm=comm)
655

656 7
    assert len(model.children) == 2
657 7
    title, widget = model.children
658 7
    assert isinstance(title, Div)
659 7
    assert isinstance(widget, Slider)
660 7
    assert widget.title == 'A'
661

662 7
    pane.show_labels = False
663

664 7
    assert len(model.children) == 2
665 7
    assert isinstance(model.children[1], Slider)
666 7
    assert model.children[1].title == ''
667

668

669 7
def test_expand_param_subobject(document, comm):
670 7
    class Test(param.Parameterized):
671 7
        a = param.Parameter()
672

673 7
    test = Test(a=Test(name='Nested'))
674 7
    test_pane = Pane(test)
675 7
    model = test_pane.get_root(document, comm=comm)
676

677 7
    toggle = model.children[1].children[1]
678 7
    assert isinstance(toggle, Toggle)
679

680
    # Expand subpane
681 7
    test_pane._widgets['a'][1].value = True
682 7
    assert len(model.children) == 3
683 7
    _, _, subpanel = test_pane.layout.objects
684 7
    col = model.children[2]
685 7
    assert isinstance(col, BkColumn)
686 7
    assert isinstance(col, BkColumn)
687 7
    assert len(col.children) == 2
688 7
    div, widget = col.children
689 7
    assert div.text == '<b>Nested</b>'
690 7
    assert isinstance(widget, BkTextInput)
691

692
    # Collapse subpanel
693 7
    test_pane._widgets['a'][1].value = False
694 7
    assert len(model.children) == 2
695

696

697 7
def test_switch_param_subobject(document, comm):
698 7
    class Test(param.Parameterized):
699 7
        a = param.ObjectSelector()
700

701 7
    o1 = Test(name='Subobject 1')
702 7
    o2 = Test(name='Subobject 2')
703 7
    Test.param['a'].objects = [o1, o2, 3]
704 7
    test = Test(a=o1, name='Nested')
705 7
    test_pane = Pane(test)
706 7
    model = test_pane.get_root(document, comm=comm)
707

708 7
    toggle = model.children[1].children[1]
709 7
    assert isinstance(toggle, Toggle)
710

711
    # Expand subpane
712 7
    test_pane._widgets['a'][1].value = True
713 7
    assert len(model.children) == 3
714 7
    _, _, subpanel = test_pane.layout.objects
715 7
    col = model.children[2]
716 7
    assert isinstance(col, BkColumn)
717 7
    assert len(col.children) == 2
718 7
    div, row = col.children
719 7
    assert div.text == '<b>Subobject 1</b>'
720 7
    assert isinstance(row.children[0], Select)
721

722
    # Switch subobject
723 7
    test_pane._widgets['a'][0].value = o2
724 7
    _, _, subpanel = test_pane.layout.objects
725 7
    col = model.children[2]
726 7
    assert isinstance(col, BkColumn)
727 7
    assert len(col.children) == 2
728 7
    div, row = col.children
729 7
    assert div.text == '<b>Subobject 2</b>'
730 7
    assert isinstance(row.children[0], Select)
731

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

737

738

739 7
def test_expand_param_subobject_into_row(document, comm):
740 7
    class Test(param.Parameterized):
741 7
        a = param.Parameter()
742

743 7
    test = Test(a=Test(name='Nested'))
744 7
    row = Row()
745 7
    test_pane = Pane(test, expand_layout=row)
746 7
    layout = Row(test_pane, row)
747 7
    model = layout.get_root(document, comm=comm)
748

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

752
    # Expand subpane
753 7
    test_pane._widgets['a'][1].value = True
754 7
    assert len(model.children) == 2
755 7
    subpanel = row.objects[0]
756 7
    row = model.children[1]
757 7
    assert isinstance(row, BkRow)
758 7
    assert len(row.children) == 1
759 7
    box = row.children[0]
760 7
    assert isinstance(box, BkColumn)
761 7
    assert len(box.children) == 2
762 7
    div, widget = box.children
763 7
    assert div.text == '<b>Nested</b>'
764 7
    assert isinstance(widget, BkTextInput)
765

766
    # Collapse subpanel
767 7
    test_pane._widgets['a'][1].value = False
768 7
    assert len(row.children) == 0
769 7
    assert subpanel._models == {}
770

771

772 7
def test_expand_param_subobject_expand(document, comm):
773 7
    class Test(param.Parameterized):
774 7
        a = param.Parameter()
775

776 7
    test = Test(a=Test(name='Nested'))
777 7
    test_pane = Pane(test, expand=True, expand_button=True)
778 7
    model = test_pane.get_root(document, comm=comm)
779

780 7
    toggle = model.children[1].children[1]
781 7
    assert isinstance(toggle, Toggle)
782

783
    # Expand subpane
784 7
    assert len(model.children) == 3
785 7
    _, _, subpanel = test_pane.layout.objects
786 7
    col = model.children[2]
787 7
    assert isinstance(col, BkColumn)
788 7
    assert len(col.children) == 2
789 7
    div, widget = col.children
790 7
    assert div.text == '<b>Nested</b>'
791 7
    assert isinstance(widget, BkTextInput)
792

793
    # Collapse subpanel
794 7
    test_pane._widgets['a'][1].value = False
795 7
    assert len(model.children) == 2
796 7
    assert subpanel._models == {}
797

798

799 7
def test_param_subobject_expand_no_toggle(document, comm):
800 7
    class Test(param.Parameterized):
801 7
        a = param.Parameter()
802

803 7
    test = Test(a=Test(name='Nested'))
804 7
    test_pane = Pane(test, expand=True,
805
                     expand_button=False)
806 7
    model = test_pane.get_root(document, comm=comm)
807

808
    # Assert no toggle was added
809 7
    assert len(model.children) == 3
810

811
    # Expand subpane
812 7
    _, _, subpanel = test_pane.layout.objects
813 7
    div, widget = model.children[2].children
814 7
    assert div.text == '<b>Nested</b>'
815 7
    assert isinstance(widget, BkTextInput)
816

817

818 7
def test_expand_param_subobject_tabs(document, comm):
819 7
    class Test(param.Parameterized):
820 7
        abc = param.Parameter()
821

822 7
    test = Test(abc=Test(name='Nested'), name='A')
823 7
    test_pane = Pane(test, expand_layout=Tabs)
824 7
    model = test_pane.get_root(document, comm=comm)
825

826 7
    toggle = model.tabs[0].child.children[0].children[1]
827 7
    assert isinstance(toggle, Toggle)
828

829
    # Expand subpanel
830 7
    test_pane._widgets['abc'][1].value = True
831 7
    assert len(model.tabs) == 2
832 7
    _, subpanel = test_pane.layout.objects
833 7
    subtabs = model.tabs[1].child
834 7
    assert model.tabs[1].title == 'Abc'
835 7
    assert isinstance(subtabs, BkTabs)
836 7
    assert len(subtabs.tabs) == 1
837 7
    assert subtabs.tabs[0].title == 'Nested'
838

839 7
    box = subtabs.tabs[0].child
840 7
    assert isinstance(box, BkColumn)
841 7
    assert len(box.children) == 1
842 7
    widget = box.children[0]
843 7
    assert isinstance(widget, BkTextInput)
844

845
    # Collapse subpanel
846 7
    test_pane._widgets['abc'][1].value = False
847 7
    assert len(model.tabs) == 1
848

849

850 7
def test_param_js_callbacks(document, comm):
851 7
    class JsButton(param.Parameterized):
852 7
        param_btn = param.Action(lambda self: print('Action Python Response'), label='Action')
853

854 7
    param_button = Param(JsButton())
855 7
    code = "console.log('Action button clicked')"
856 7
    param_button[1].js_on_click(code=code)
857

858 7
    model = param_button.get_root(document, comm=comm)
859

860 7
    button = model.children[1]
861 7
    assert len(button.js_event_callbacks) == 1
862 7
    callbacks = button.js_event_callbacks
863 7
    assert 'button_click' in callbacks
864 7
    assert len(callbacks['button_click']) == 1
865 7
    assert code in callbacks['button_click'][0].code
866

867

868 7
class View(param.Parameterized):
869

870 7
    a = param.Integer(default=0)
871

872 7
    b = param.Parameter()
873

874 7
    @param.depends('a')
875 2
    def view(self):
876 7
        return Div(text='%d' % self.a)
877

878 7
    @param.depends('b.param')
879 2
    def subobject_view(self):
880 7
        return Div(text='%d' % self.b.a)
881

882 7
    @param.depends('a')
883 2
    def mpl_view(self):
884 7
        return mpl_figure()
885

886 7
    @param.depends('a')
887 2
    def mixed_view(self):
888 7
        return self.view() if (self.a % 2) else self.mpl_view()
889

890

891 7
def test_get_param_function_pane_type():
892 7
    test = View()
893

894 7
    def view(a):
895 0
        return Div(text='%d' % a)
896

897 7
    assert PaneBase.get_pane_type(view) is not ParamFunction
898 7
    assert PaneBase.get_pane_type(param.depends(test.param.a)(view)) is ParamFunction
899

900

901 7
def test_param_function_pane(document, comm):
902 7
    test = View()
903

904 7
    @param.depends(test.param.a)
905 2
    def view(a):
906 7
        return Div(text='%d' % a)
907

908 7
    pane = Pane(view)
909 7
    inner_pane = pane._pane
910 7
    assert isinstance(inner_pane, Bokeh)
911

912
    # Create pane
913 7
    row = pane.get_root(document, comm=comm)
914 7
    assert isinstance(row, BkRow)
915 7
    assert len(row.children) == 1
916 7
    model = row.children[0]
917 7
    assert pane._models[row.ref['id']][0] is row
918 7
    assert isinstance(model, Div)
919 7
    assert model.text == '0'
920

921
    # Update pane
922 7
    test.a = 5
923 7
    new_model = row.children[0]
924 7
    assert inner_pane is pane._pane
925 7
    assert new_model.text == '5'
926 7
    assert pane._models[row.ref['id']][0] is row
927

928
    # Cleanup pane
929 7
    pane._cleanup(row)
930 7
    assert pane._models == {}
931 7
    assert inner_pane._models == {}
932

933

934 7
def test_param_function_pane_update(document, comm):
935 7
    test = View()
936

937 7
    objs = {
938
        0: HTML("012"),
939
        1: HTML("123")
940
    }
941

942 7
    @param.depends(test.param.a)
943 2
    def view(a):
944 7
        return objs[a]
945

946 7
    pane = Pane(view)
947 7
    inner_pane = pane._pane
948 7
    assert inner_pane is not objs[0]
949 7
    assert inner_pane.object is objs[0].object
950 7
    assert pane._internal
951

952 7
    test.a = 1
953

954 7
    assert pane._pane is inner_pane
955 7
    assert pane._internal
956

957 7
    objs[0].param.watch(print, ['object'])
958

959 7
    test.a = 0
960

961 7
    assert pane._pane is not inner_pane
962 7
    assert not pane._internal
963

964

965 7
def test_get_param_method_pane_type():
966 7
    assert PaneBase.get_pane_type(View().view) is ParamMethod
967

968

969 7
def test_param_method_pane(document, comm):
970 7
    test = View()
971 7
    pane = Pane(test.view)
972 7
    inner_pane = pane._pane
973 7
    assert isinstance(inner_pane, Bokeh)
974

975
    # Create pane
976 7
    row = pane.get_root(document, comm=comm)
977 7
    assert isinstance(row, BkRow)
978 7
    assert len(row.children) == 1
979 7
    model = row.children[0]
980 7
    assert pane._models[row.ref['id']][0] is row
981 7
    assert isinstance(model, Div)
982 7
    assert model.text == '0'
983

984
    # Update pane
985 7
    test.a = 5
986 7
    new_model = row.children[0]
987 7
    assert inner_pane is pane._pane
988 7
    assert new_model.text == '5'
989 7
    assert pane._models[row.ref['id']][0] is row
990

991
    # Cleanup pane
992 7
    pane._cleanup(row)
993 7
    assert pane._models == {}
994 7
    assert inner_pane._models == {}
995

996

997 7
def test_param_method_pane_subobject(document, comm):
998 7
    subobject = View(name='Nested', a=42)
999 7
    test = View(b=subobject)
1000 7
    pane = Pane(test.subobject_view)
1001 7
    inner_pane = pane._pane
1002 7
    assert isinstance(inner_pane, Bokeh)
1003

1004
    # Create pane
1005 7
    row = pane.get_root(document, comm=comm)
1006 7
    assert isinstance(row, BkRow)
1007 7
    assert len(row.children) == 1
1008 7
    model = row.children[0]
1009 7
    assert isinstance(model, Div)
1010 7
    assert model.text == '42'
1011

1012
    # Ensure that subobject is being watched
1013 7
    watchers = pane._callbacks
1014 7
    assert any(w.inst is subobject for w in watchers)
1015 7
    assert pane._models[row.ref['id']][0] is row
1016

1017
    # Ensure that switching the subobject triggers update in watchers
1018 7
    new_subobject = View(name='Nested', a=42)
1019 7
    test.b = new_subobject
1020 7
    assert pane._models[row.ref['id']][0] is row
1021 7
    watchers = pane._callbacks
1022 7
    assert not any(w.inst is subobject for w in watchers)
1023 7
    assert any(w.inst is new_subobject for w in watchers)
1024

1025
    # Cleanup pane
1026 7
    pane._cleanup(row)
1027 7
    assert pane._models == {}
1028 7
    assert inner_pane._models == {}
1029

1030

1031 7
@mpl_available
1032 2
def test_param_method_pane_mpl(document, comm):
1033 7
    test = View()
1034 7
    pane = Pane(test.mpl_view)
1035 7
    inner_pane = pane._pane
1036 7
    assert isinstance(inner_pane, Matplotlib)
1037

1038
    # Create pane
1039 7
    row = pane.get_root(document, comm=comm)
1040 7
    assert isinstance(row, BkRow)
1041 7
    assert len(row.children) == 1
1042 7
    model = row.children[0]
1043 7
    assert pane._models[row.ref['id']][0] is row
1044 7
    text = model.text
1045

1046
    # Update pane
1047 7
    test.a = 5
1048 7
    new_model = row.children[0]
1049 7
    assert inner_pane is pane._pane
1050 7
    assert new_model is model
1051 7
    assert new_model.text != text
1052 7
    assert pane._models[row.ref['id']][0] is row
1053

1054
    # Cleanup pane
1055 7
    pane._cleanup(row)
1056 7
    assert pane._models == {}
1057 7
    assert inner_pane._models == {}
1058

1059

1060 7
@mpl_available
1061 2
def test_param_method_pane_changing_type(document, comm):
1062 7
    test = View()
1063 7
    pane = Pane(test.mixed_view)
1064 7
    inner_pane = pane._pane
1065 7
    assert isinstance(inner_pane, Matplotlib)
1066

1067
    # Create pane
1068 7
    row = pane.get_root(document, comm=comm)
1069 7
    assert isinstance(row, BkRow)
1070 7
    assert len(row.children) == 1
1071 7
    model = row.children[0]
1072 7
    text = model.text
1073 7
    assert text.startswith('&lt;img src=')
1074

1075
    # Update pane
1076 7
    test.a = 5
1077 7
    new_model = row.children[0]
1078 7
    new_pane = pane._pane
1079 7
    assert isinstance(new_pane, Bokeh)
1080 7
    assert isinstance(new_model, Div)
1081 7
    assert new_model.text != text
1082

1083
    # Cleanup pane
1084 7
    new_pane._cleanup(row)
1085 7
    assert new_pane._models == {}
1086

1087

1088 7
def test_jsoninit_class_from_env_var():
1089 7
    os.environ['PARAM_JSON_INIT'] = '{"a": 1}'
1090

1091 7
    json_init = JSONInit()
1092

1093 7
    class Test(param.Parameterized):
1094 7
        a = param.Integer()
1095

1096 7
    json_init(Test)
1097

1098 7
    assert Test.a == 1
1099 7
    del os.environ['PARAM_JSON_INIT']
1100

1101

1102 7
def test_jsoninit_instance_from_env_var():
1103 7
    os.environ['PARAM_JSON_INIT'] = '{"a": 2}'
1104

1105 7
    json_init = JSONInit()
1106

1107 7
    class Test(param.Parameterized):
1108 7
        a = param.Integer()
1109

1110 7
    test = Test()
1111 7
    json_init(test)
1112

1113 7
    assert test.a == 2
1114 7
    del os.environ['PARAM_JSON_INIT']
1115

1116 7
def test_change_object_and_keep_parameters():
1117
    """Test that https://github.com/holoviz/panel/issues/1581 is solved"""
1118
    # Given
1119 7
    class TextModel(param.Parameterized):
1120 7
        text = param.String()
1121 7
        param2 = param.String()
1122

1123 7
    class TextView(param.Parameterized):
1124 7
        text = param.ClassSelector(class_=TextModel)
1125 7
        text_pane = param.Parameter()
1126

1127 7
        def __init__(self, **params):
1128 7
            params["text"] = TextModel(text="Original Text")
1129 7
            super().__init__(**params)
1130

1131 7
            self.text_pane = Param(
1132
                self.text, parameters=["text"]
1133
            )
1134

1135 7
        @param.depends("text", watch=True)
1136 2
        def _update_text_pane(self, *_):
1137 7
            self.text_pane.object = self.text
1138

1139 7
    view = TextView()
1140 7
    assert view.text_pane.parameters==["text"]
1141

1142
    # When
1143 7
    view.text = TextModel(text="New TextModel")
1144
    # Then
1145 7
    assert view.text_pane.parameters==["text"]

Read our documentation on viewing source code .

Loading