1 7
from __future__ import absolute_import, division, unicode_literals, print_function
2

3 7
import os
4 7
import json
5 7
import glob
6 7
import pytest
7

8 7
from io import StringIO
9

10 7
from bokeh.models import CustomJS
11

12 7
from panel import Row
13 7
from panel.config import config
14 7
from panel.io.embed import embed_state
15 7
from panel.pane import Str
16 7
from panel.param import Param
17 7
from panel.widgets import IntSlider, Select, FloatSlider, Checkbox, StaticText
18

19

20 7
def test_embed_param_jslink(document, comm):
21 7
    select = Select(options=['A', 'B', 'C'])
22 7
    params = Param(select, parameters=['disabled']).layout
23 7
    panel = Row(select, params)
24 7
    with config.set(embed=True):
25 7
        model = panel.get_root(document, comm)
26 7
    embed_state(panel, model, document)
27 7
    assert len(document.roots) == 1
28

29 7
    ref = model.ref['id']
30 7
    cbs = list(model.select({'type': CustomJS}))
31 7
    assert len(cbs) == 2
32 7
    cb1, cb2 = cbs
33 7
    cb1, cb2 = (cb1, cb2) if select._models[ref][0] is cb1.args['target'] else (cb2, cb1)
34 7
    assert cb1.code == """
35
    var value = source['active'];
36
    value = value.indexOf(0) >= 0;
37
    value = value;
38
    try {
39
      var property = target.properties['disabled'];
40
      if (property !== undefined) { property.validate(value); }
41
    } catch(err) {
42
      console.log('WARNING: Could not set disabled on target, raised error: ' + err);
43
      return;
44
    }
45
    try {
46
      target['disabled'] = value;
47
    } catch(err) {
48
      console.log(err)
49
    }
50
    """
51

52 7
    assert cb2.code == """
53
    var value = source['disabled'];
54
    value = value;
55
    value = value ? [0] : [];
56
    try {
57
      var property = target.properties['active'];
58
      if (property !== undefined) { property.validate(value); }
59
    } catch(err) {
60
      console.log('WARNING: Could not set active on target, raised error: ' + err);
61
      return;
62
    }
63
    try {
64
      target['active'] = value;
65
    } catch(err) {
66
      console.log(err)
67
    }
68
    """
69

70

71 7
def test_embed_select_str_link(document, comm):
72 7
    select = Select(options=['A', 'B', 'C'])
73 7
    string = Str()
74 7
    def link(target, event):
75 7
        target.object = event.new
76 7
    select.link(string, callbacks={'value': link})
77 7
    panel = Row(select, string)
78 7
    with config.set(embed=True):
79 7
        model = panel.get_root(document, comm)
80 7
    embed_state(panel, model, document)
81 7
    _, state = document.roots
82 7
    assert set(state.state) == {'A', 'B', 'C'}
83 7
    for k, v in state.state.items():
84 7
        content = json.loads(v['content'])
85 7
        assert 'events' in content
86 7
        events = content['events']
87 7
        assert len(events) == 1
88 7
        event = events[0]
89 7
        assert event['kind'] == 'ModelChanged'
90 7
        assert event['attr'] == 'text'
91 7
        assert event['model'] == model.children[1].ref
92 7
        assert event['new'] == '<pre>%s</pre>' % k
93

94

95 7
def test_embed_float_slider_explicit_values(document, comm):
96 7
    select = FloatSlider()
97 7
    string = Str()
98 7
    def link(target, event):
99 7
        target.object = event.new
100 7
    select.link(string, callbacks={'value': link})
101 7
    panel = Row(select, string)
102 7
    with config.set(embed=True):
103 7
        model = panel.get_root(document, comm)
104 7
    embed_state(panel, model, document, states={select: [0.1, 0.7, 1]})
105 7
    _, state = document.roots
106 7
    assert set(state.state) == {0, 1, 2}
107 7
    states = {0: 0.1, 1: 0.7, 2: 1}
108 7
    for (k, v) in state.state.items():
109 7
        content = json.loads(v['content'])
110 7
        assert 'events' in content
111 7
        events = content['events']
112 7
        assert len(events) == 1
113 7
        event = events[0]
114 7
        assert event['kind'] == 'ModelChanged'
115 7
        assert event['attr'] == 'text'
116 7
        assert event['model'] == model.children[1].ref
117 7
        assert event['new'] == '<pre>%s</pre>' % states[k]
118

119

120 7
def test_embed_select_explicit_values(document, comm):
121 7
    select = Select(options=['A', 'B', 'C'])
122 7
    string = Str()
123 7
    def link(target, event):
124 7
        target.object = event.new
125 7
    select.link(string, callbacks={'value': link})
126 7
    panel = Row(select, string)
127 7
    with config.set(embed=True):
128 7
        model = panel.get_root(document, comm)
129 7
    embed_state(panel, model, document, states={select: ['A', 'B']})
130 7
    _, state = document.roots
131 7
    assert set(state.state) == {'A', 'B'}
132 7
    for k, v in state.state.items():
133 7
        content = json.loads(v['content'])
134 7
        assert 'events' in content
135 7
        events = content['events']
136 7
        assert len(events) == 1
137 7
        event = events[0]
138 7
        assert event['kind'] == 'ModelChanged'
139 7
        assert event['attr'] == 'text'
140 7
        assert event['model'] == model.children[1].ref
141 7
        assert event['new'] == '<pre>%s</pre>' % k
142

143

144 7
def test_embed_select_str_explicit_values_not_found(document, comm):
145 7
    select = Select(options=['A', 'B', 'C'])
146 7
    string = Str()
147 7
    def link(target, event):
148 0
        target.object = event.new
149 7
    select.link(string, callbacks={'value': link})
150 7
    panel = Row(select, string)
151 7
    with config.set(embed=True):
152 7
        model = panel.get_root(document, comm)
153 7
    with pytest.raises(ValueError):
154 7
        embed_state(panel, model, document, states={select: ['A', 'D']})
155

156

157 7
def test_embed_float_slider_explicit_values_out_of_bounds(document, comm):
158 7
    select = FloatSlider()
159 7
    string = Str()
160 7
    def link(target, event):
161 0
        target.object = event.new
162 7
    select.link(string, callbacks={'value': link})
163 7
    panel = Row(select, string)
164 7
    with config.set(embed=True):
165 7
        model = panel.get_root(document, comm)
166 7
    with pytest.raises(ValueError):
167 7
        embed_state(panel, model, document, states={select: [0.1, 0.7, 2]})
168

169

170 7
def test_embed_select_str_link_two_steps(document, comm):
171 7
    select = Select(options=['A', 'B', 'C'])
172 7
    string1 = Str()
173 7
    select.link(string1, value='object')
174 7
    string2 = Str()
175 7
    string1.link(string2, object='object')
176 7
    panel = Row(select, string1, string2)
177 7
    with config.set(embed=True):
178 7
        model = panel.get_root(document, comm)
179 7
    embed_state(panel, model, document)
180 7
    _, state = document.roots
181 7
    assert set(state.state) == {'A', 'B', 'C'}
182 7
    for k, v in state.state.items():
183 7
        content = json.loads(v['content'])
184 7
        assert 'events' in content
185 7
        events = content['events']
186 7
        assert len(events) == 2
187 7
        event = events[0]
188 7
        assert event['kind'] == 'ModelChanged'
189 7
        assert event['attr'] == 'text'
190 7
        assert event['model'] == model.children[1].ref
191 7
        assert event['new'] == '<pre>%s</pre>' % k
192

193 7
        event = events[1]
194 7
        assert event['kind'] == 'ModelChanged'
195 7
        assert event['attr'] == 'text'
196 7
        assert event['model'] == model.children[2].ref
197 7
        assert event['new'] == '<pre>%s</pre>' % k
198

199

200 7
def test_embed_select_str_link_with_secondary_watch(document, comm):
201 7
    select = Select(options=['A', 'B', 'C'])
202 7
    string = Str()
203 7
    select.link(string, value='object')
204 7
    string.param.watch(print, 'object')
205 7
    panel = Row(select, string)
206 7
    with config.set(embed=True):
207 7
        model = panel.get_root(document, comm)
208 7
    embed_state(panel, model, document)
209 7
    _, state = document.roots
210 7
    assert set(state.state) == {'A', 'B', 'C'}
211 7
    for k, v in state.state.items():
212 7
        content = json.loads(v['content'])
213 7
        assert 'events' in content
214 7
        events = content['events']
215 7
        assert len(events) == 1
216 7
        event = events[0]
217 7
        assert event['kind'] == 'ModelChanged'
218 7
        assert event['attr'] == 'text'
219 7
        assert event['model'] == model.children[1].ref
220 7
        assert event['new'] == '<pre>%s</pre>' % k
221

222

223 7
def test_embed_select_str_jslink(document, comm):
224 7
    select = Select(options=['A', 'B', 'C'])
225 7
    string = Str()
226 7
    select.link(string, value='object')
227 7
    panel = Row(select, string)
228 7
    with config.set(embed=True):
229 7
        model = panel.get_root(document, comm)
230 7
    embed_state(panel, model, document)
231 7
    assert len(document.roots) == 1
232 7
    assert model is document.roots[0]
233

234 7
    ref = model.ref['id']
235 7
    cbs = list(model.select({'type': CustomJS}))
236 7
    assert len(cbs) == 2
237 7
    cb1, cb2 = cbs
238 7
    cb1, cb2 = (cb1, cb2) if select._models[ref][0] is cb1.args['source'] else (cb2, cb1)
239 7
    assert cb1.code == """
240
    var value = source['value'];
241
    value = value;
242
    value = JSON.stringify(value).replace(/,/g, ", ").replace(/:/g, ": ");
243
    try {
244
      var property = target.properties['text'];
245
      if (property !== undefined) { property.validate(value); }
246
    } catch(err) {
247
      console.log('WARNING: Could not set text on target, raised error: ' + err);
248
      return;
249
    }
250
    try {
251
      target['text'] = value;
252
    } catch(err) {
253
      console.log(err)
254
    }
255
    """
256

257 7
    assert cb2.code == """
258
    var value = source['text'];
259
    value = value;
260
    value = value;
261
    try {
262
      var property = target.properties['value'];
263
      if (property !== undefined) { property.validate(value); }
264
    } catch(err) {
265
      console.log('WARNING: Could not set value on target, raised error: ' + err);
266
      return;
267
    }
268
    try {
269
      target['value'] = value;
270
    } catch(err) {
271
      console.log(err)
272
    }
273
    """
274

275

276 7
def test_embed_checkbox_str_link(document, comm):
277 7
    checkbox = Checkbox()
278 7
    string = Str()
279 7
    def link(target, event):
280 7
        target.object = event.new
281 7
    checkbox.link(string, callbacks={'value': link})
282 7
    panel = Row(checkbox, string)
283 7
    with config.set(embed=True):
284 7
        model = panel.get_root(document, comm)
285 7
    embed_state(panel, model, document)
286 7
    _, state = document.roots
287 7
    assert set(state.state) == {'false', 'true'}
288 7
    for k, v in state.state.items():
289 7
        content = json.loads(v['content'])
290 7
        assert 'events' in content
291 7
        events = content['events']
292 7
        assert len(events) == 1
293 7
        event = events[0]
294 7
        assert event['kind'] == 'ModelChanged'
295 7
        assert event['attr'] == 'text'
296 7
        assert event['model'] == model.children[1].ref
297 7
        assert event['new'] == '<pre>%s</pre>' % k.title()
298

299

300 7
def test_embed_checkbox_str_jslink(document, comm):
301 7
    checkbox = Checkbox()
302 7
    string = Str()
303 7
    checkbox.link(string, value='object')
304 7
    panel = Row(checkbox, string)
305 7
    with config.set(embed=True):
306 7
        model = panel.get_root(document, comm)
307 7
    embed_state(panel, model, document)
308 7
    assert len(document.roots) == 1
309 7
    assert model is document.roots[0]
310

311 7
    ref = model.ref['id']
312 7
    cbs = list(model.select({'type': CustomJS}))
313 7
    assert len(cbs) == 2
314 7
    cb1, cb2 = cbs
315 7
    cb1, cb2 = (cb1, cb2) if checkbox._models[ref][0] is cb1.args['source'] else (cb2, cb1)
316 7
    assert cb1.code == """
317
    var value = source['active'];
318
    value = value.indexOf(0) >= 0;
319
    value = JSON.stringify(value).replace(/,/g, ", ").replace(/:/g, ": ");
320
    try {
321
      var property = target.properties['text'];
322
      if (property !== undefined) { property.validate(value); }
323
    } catch(err) {
324
      console.log('WARNING: Could not set text on target, raised error: ' + err);
325
      return;
326
    }
327
    try {
328
      target['text'] = value;
329
    } catch(err) {
330
      console.log(err)
331
    }
332
    """
333

334 7
    assert cb2.code == """
335
    var value = source['text'];
336
    value = value;
337
    value = value ? [0] : [];
338
    try {
339
      var property = target.properties['active'];
340
      if (property !== undefined) { property.validate(value); }
341
    } catch(err) {
342
      console.log('WARNING: Could not set active on target, raised error: ' + err);
343
      return;
344
    }
345
    try {
346
      target['active'] = value;
347
    } catch(err) {
348
      console.log(err)
349
    }
350
    """
351

352

353 7
def test_embed_slider_str_link(document, comm):
354 7
    slider = FloatSlider(start=0, end=10)
355 7
    string = Str()
356 7
    def link(target, event):
357 7
        target.object = event.new
358 7
    slider.link(string, callbacks={'value': link})
359 7
    panel = Row(slider, string)
360 7
    with config.set(embed=True):
361 7
        model = panel.get_root(document, comm)
362 7
    embed_state(panel, model, document)
363 7
    _, state = document.roots
364 7
    assert set(state.state) == {0, 1, 2}
365 7
    values = [0, 5, 10]
366 7
    for k, v in state.state.items():
367 7
        content = json.loads(v['content'])
368 7
        assert 'events' in content
369 7
        events = content['events']
370 7
        assert len(events) == 1
371 7
        event = events[0]
372 7
        assert event['kind'] == 'ModelChanged'
373 7
        assert event['attr'] == 'text'
374 7
        assert event['model'] == model.children[1].ref
375 7
        assert event['new'] == '<pre>%.1f</pre>' % values[k]
376

377

378 7
def test_embed_slider_str_jslink(document, comm):
379 7
    slider = FloatSlider(start=0, end=10)
380 7
    string = Str()
381 7
    slider.link(string, value='object')
382 7
    panel = Row(slider, string)
383 7
    with config.set(embed=True):
384 7
        model = panel.get_root(document, comm)
385 7
    embed_state(panel, model, document)
386 7
    assert len(document.roots) == 1
387 7
    assert model is document.roots[0]
388

389 7
    ref = model.ref['id']
390 7
    cbs = list(model.select({'type': CustomJS}))
391 7
    assert len(cbs) == 2
392 7
    cb1, cb2 = cbs
393 7
    cb1, cb2 = (cb1, cb2) if slider._models[ref][0] is cb1.args['source'] else (cb2, cb1)
394 7
    assert cb1.code == """
395
    var value = source['value'];
396
    value = value;
397
    value = JSON.stringify(value).replace(/,/g, ", ").replace(/:/g, ": ");
398
    try {
399
      var property = target.properties['text'];
400
      if (property !== undefined) { property.validate(value); }
401
    } catch(err) {
402
      console.log('WARNING: Could not set text on target, raised error: ' + err);
403
      return;
404
    }
405
    try {
406
      target['text'] = value;
407
    } catch(err) {
408
      console.log(err)
409
    }
410
    """
411

412 7
    assert cb2.code == """
413
    var value = source['text'];
414
    value = value;
415
    value = value;
416
    try {
417
      var property = target.properties['value'];
418
      if (property !== undefined) { property.validate(value); }
419
    } catch(err) {
420
      console.log('WARNING: Could not set value on target, raised error: ' + err);
421
      return;
422
    }
423
    try {
424
      target['value'] = value;
425
    } catch(err) {
426
      console.log(err)
427
    }
428
    """
429

430

431 7
def test_embed_merged_sliders(document, comm):
432 7
    s1 = IntSlider(name='A', start=1, end=10, value=1)
433 7
    t1 = StaticText()
434 7
    s1.param.watch(lambda event: setattr(t1, 'value', event.new), 'value')
435

436 7
    s2 = IntSlider(name='A', start=1, end=10, value=1)
437 7
    t2 = StaticText()
438 7
    s2.param.watch(lambda event: setattr(t2, 'value', event.new), 'value')
439

440 7
    panel = Row(s1, s2, t1, t2)
441 7
    with config.set(embed=True):
442 7
        model = panel.get_root(document, comm)
443 7
    state_model = embed_state(panel, model, document)
444 7
    assert len(document.roots) == 2
445 7
    assert model is document.roots[0]
446

447 7
    cbs = list(model.select({'type': CustomJS}))
448 7
    assert len(cbs) == 5
449

450 7
    ref1, ref2 = model.children[2].ref['id'], model.children[3].ref['id']
451 7
    state0 = json.loads(state_model.state[0]['content'])['events']
452 7
    assert state0 == [
453
        {"attr": "text", "kind": "ModelChanged", "model": {"id": ref1}, "new": "1"},
454
        {"attr": "text", "kind": "ModelChanged", "model": {"id": ref2}, "new": "1"}
455
    ]
456 7
    state1 = json.loads(state_model.state[1]['content'])['events']
457 7
    assert state1 == [
458
        {"attr": "text", "kind": "ModelChanged", "model": {"id": ref1}, "new": "5"},
459
        {"attr": "text", "kind": "ModelChanged", "model": {"id": ref2}, "new": "5"}
460
    ]
461 7
    state2 = json.loads(state_model.state[2]['content'])['events']
462 7
    assert state2 == [
463
        {"attr": "text", "kind": "ModelChanged", "model": {"id": ref1}, "new": "9"},
464
        {"attr": "text", "kind": "ModelChanged", "model": {"id": ref2}, "new": "9"}
465
    ]
466

467

468 7
def test_save_embed_bytesio():
469 7
    checkbox = Checkbox()
470 7
    string = Str()
471 7
    def link(target, event):
472 7
        target.object = event.new
473 7
    checkbox.link(string, callbacks={'value': link})
474 7
    panel = Row(checkbox, string)
475 7
    stringio = StringIO()
476 7
    panel.save(stringio, embed=True)
477 7
    stringio.seek(0)
478 7
    utf = stringio.read()
479 7
    assert "<pre>False</pre>" in utf
480 7
    assert "<pre>True</pre>" in utf
481

482

483 7
def test_save_embed(tmpdir):
484 7
    checkbox = Checkbox()
485 7
    string = Str()
486 7
    checkbox.link(string, value='object')
487 7
    panel = Row(checkbox, string)
488 7
    filename = os.path.join(str(tmpdir), 'test.html')
489 7
    panel.save(filename, embed=True)
490 7
    assert os.path.isfile(filename)
491

492

493 7
def test_save_embed_json(tmpdir):
494 7
    checkbox = Checkbox()
495 7
    string = Str()
496 7
    def link(target, event):
497 7
        target.object = event.new
498 7
    checkbox.link(string, callbacks={'value': link})
499 7
    panel = Row(checkbox, string)
500 7
    filename = os.path.join(str(tmpdir), 'test.html')
501 7
    panel.save(filename, embed=True, embed_json=True,
502
               save_path=str(tmpdir))
503 7
    assert os.path.isfile(filename)
504 7
    paths = glob.glob(os.path.join(str(tmpdir), '*'))
505 7
    paths.remove(filename)
506 7
    assert len(paths) == 1
507 7
    json_files = sorted(glob.glob(os.path.join(paths[0], '*.json')))
508 7
    assert len(json_files) == 2
509

510 7
    for jf, v in zip(json_files, ('False', 'True')):
511 7
        with open(jf) as f:
512 7
            state = json.load(f)
513 7
        assert 'content' in state
514 7
        assert 'events' in state['content']
515 7
        events = json.loads(state['content'])['events']
516 7
        assert len(events) == 1
517 7
        event = events[0]
518 7
        assert event['kind'] == 'ModelChanged'
519 7
        assert event['attr'] == 'text'
520 7
        assert event['new'] == '<pre>%s</pre>' % v

Read our documentation on viewing source code .

Loading