from datetime import datetime, date
import numpy as np
import pytest
from bokeh.models.widgets import FileInput as BkFileInput
from panel import config
from panel.widgets import (
ArrayInput, Checkbox, DatePicker, DatetimeInput, DatetimePicker,
DatetimeRangeInput, DatetimeRangePicker, FileInput, LiteralInput,
TextInput, StaticText, IntInput, FloatInput
)
def test_checkbox(document, comm):
checkbox = Checkbox(value=True, name='Checkbox')
widget = checkbox.get_root(document, comm=comm)
assert isinstance(widget, checkbox._widget_type)
assert widget.labels == ['Checkbox']
assert widget.active == [0]
widget.active = []
checkbox._process_events({'active': []})
assert checkbox.value == False
checkbox.value = True
assert widget.active == [0]
def test_date_picker(document, comm):
date_picker = DatePicker(name='DatePicker', value=date(2018, 9, 2),
start=date(2018, 9, 1), end=date(2018, 9, 10))
widget = date_picker.get_root(document, comm=comm)
assert isinstance(widget, date_picker._widget_type)
assert widget.title == 'DatePicker'
assert widget.value == '2018-09-02'
assert widget.min_date == '2018-09-01'
assert widget.max_date == '2018-09-10'
widget.value = '2018-09-03'
date_picker._process_events({'value': '2018-09-03'})
assert date_picker.value == date(2018, 9, 3)
date_picker._process_events({'value': date(2018, 9, 5)})
assert date_picker.value == date(2018, 9, 5)
date_picker._process_events({'value': date(2018, 9, 6)})
assert date_picker.value == date(2018, 9, 6)
date_picker.value = date(2018, 9, 4)
assert widget.value == '2018-09-04'
def test_datetime_picker(document, comm):
datetime_picker = DatetimePicker(
name='DatetimePicker', value=datetime(2018, 9, 2, 1, 5),
start=date(2018, 9, 1), end=date(2018, 9, 10)
)
widget = datetime_picker.get_root(document, comm=comm)
assert isinstance(widget, datetime_picker._widget_type)
assert widget.title == 'DatetimePicker'
assert widget.value == '2018-09-02 01:05:00'
assert widget.min_date == '2018-09-01'
assert widget.max_date == '2018-09-10'
datetime_picker._process_events({'value': '2018-09-03 03:00:01'})
assert datetime_picker.value == datetime(2018, 9, 3, 3, 0, 1)
datetime_picker._process_events({'value': datetime(2018, 9, 5)})
assert datetime_picker.value == datetime(2018, 9, 5)
value = datetime_picker._process_param_change({'value': datetime(2018, 9, 4, 1, 0, 1)})
assert value['value'] == '2018-09-04 01:00:01'
value = datetime(2018, 9, 4, 12, 1)
assert datetime_picker._deserialize_value(value) == '2018-09-04 12:01:00'
assert datetime_picker._serialize_value(datetime_picker._deserialize_value(value)) == value
# Check end value
datetime_picker._process_events({'value': '2018-09-10 03:00:01'})
assert datetime_picker.value == datetime(2018, 9, 10, 0, 0, 0)
def test_datetime_range_picker(document, comm):
datetime_range_picker = DatetimeRangePicker(
name='DatetimeRangePicker', value=(datetime(2018, 9, 2, 1, 5), datetime(2018, 9, 2, 1, 6)),
start=date(2018, 9, 1), end=date(2018, 9, 10)
)
widget = datetime_range_picker.get_root(document, comm=comm)
assert isinstance(widget, datetime_range_picker._widget_type)
assert widget.title == 'DatetimeRangePicker'
assert widget.value == '2018-09-02 01:05:00 to 2018-09-02 01:06:00'
assert widget.min_date == '2018-09-01'
assert widget.max_date == '2018-09-10'
datetime_range_picker._process_events({'value': '2018-09-03 03:00:01 to 2018-09-04 03:00:01'})
assert datetime_range_picker.value == (datetime(2018, 9, 3, 3, 0, 1), datetime(2018, 9, 4, 3, 0, 1))
value = datetime_range_picker._process_param_change(
{'value': (datetime(2018, 9, 4, 1, 0, 1), datetime(2018, 9, 4, 4, 0, 1))}
)
assert value['value'] == '2018-09-04 01:00:01 to 2018-09-04 04:00:01'
value = (datetime(2018, 9, 4, 12, 1), datetime(2018, 9, 4, 12, 1, 10))
assert datetime_range_picker._deserialize_value(value) == '2018-09-04 12:01:00 to 2018-09-04 12:01:10'
assert datetime_range_picker._serialize_value(datetime_range_picker._deserialize_value(value)) == value
# Check end value
datetime_range_picker._process_events({'value': '2018-09-09 03:00:01 to 2018-09-10 03:00:01'})
assert datetime_range_picker.value == (datetime(2018, 9, 9, 3, 0, 1), datetime(2018, 9, 10, 0, 0, 0))
def test_file_input(document, comm):
file_input = FileInput(accept='.txt')
widget = file_input.get_root(document, comm=comm)
assert isinstance(widget, BkFileInput)
file_input._process_events({'mime_type': 'text/plain', 'value': 'U29tZSB0ZXh0Cg==', 'filename': 'testfile'})
assert file_input.value == b'Some text\n'
assert file_input.mime_type == 'text/plain'
assert file_input.accept == '.txt'
assert file_input.filename == 'testfile'
def test_literal_input(document, comm):
literal = LiteralInput(value={}, type=dict, name='Literal')
widget = literal.get_root(document, comm=comm)
assert isinstance(widget, literal._widget_type)
assert widget.title == 'Literal'
assert widget.value == '{}'
literal._process_events({'value': "{'key': (0, 2)}"})
assert literal.value == {'key': (0, 2)}
assert widget.title == 'Literal'
literal._process_events({'value': "(0, 2)"})
assert literal.value == {'key': (0, 2)}
assert widget.title == 'Literal (wrong type)'
literal._process_events({'value': "invalid"})
assert literal.value == {'key': (0, 2)}
assert widget.title == 'Literal (invalid)'
literal._process_events({'value': "{'key': (0, 3)}"})
assert literal.value == {'key': (0, 3)}
assert widget.title == 'Literal'
with pytest.raises(ValueError):
literal.value = []
def test_static_text(document, comm):
text = StaticText(value='ABC', name='Text:')
widget = text.get_root(document, comm=comm)
assert isinstance(widget, text._widget_type)
assert widget.text == 'Text:: ABC'
text.value = 'CBA'
assert widget.text == 'Text:: CBA'
text.value = 'Text:: ABC'
assert widget.text == 'Text:: ABC'
def test_text_input(document, comm):
text = TextInput(value='ABC', name='Text:')
widget = text.get_root(document, comm=comm)
assert isinstance(widget, text._widget_type)
assert widget.value == 'ABC'
assert widget.title == 'Text:'
text._process_events({'value': 'CBA'})
assert text.value == 'CBA'
text.value = 'A'
assert widget.value == 'A'
def test_datetime_input(document, comm):
dt_input = DatetimeInput(value=datetime(2018, 1, 1),
start=datetime(2017, 12, 31),
end=datetime(2018, 1, 10),
name='Datetime')
widget = dt_input.get_root(document, comm=comm)
assert isinstance(widget, dt_input._widget_type)
assert widget.title == 'Datetime'
assert widget.value == '2018-01-01 00:00:00'
dt_input._process_events({'value': '2018-01-01 00:00:01'})
assert dt_input.value == datetime(2018, 1, 1, 0, 0, 1)
assert widget.title == 'Datetime'
dt_input._process_events({'value': '2018-01-01 00:00:01a'})
assert dt_input.value == datetime(2018, 1, 1, 0, 0, 1)
assert widget.title == 'Datetime (invalid)'
dt_input._process_events({'value': '2018-01-11 00:00:00'})
assert dt_input.value == datetime(2018, 1, 1, 0, 0, 1)
assert widget.title == 'Datetime (out of bounds)'
dt_input._process_events({'value': '2018-01-02 00:00:01'})
assert dt_input.value == datetime(2018, 1, 2, 0, 0, 1)
assert widget.title == 'Datetime'
with pytest.raises(ValueError):
dt_input.value = datetime(2017, 12, 30)
def test_datetime_range_input(document, comm):
dt_input = DatetimeRangeInput(
value=(datetime(2018, 1, 1), datetime(2018, 1, 3)),
start=datetime(2017, 12, 31), end=datetime(2018, 1, 10),
name='Datetime')
composite = dt_input.get_root(document, comm=comm)
label, start, end = composite.children
assert isinstance(composite, dt_input._composite_type._bokeh_model)
assert label.text == 'Datetime'
assert start.value == '2018-01-01 00:00:00'
assert end.value == '2018-01-03 00:00:00'
dt_input._start._process_events({'value': '2018-01-01 00:00:01'})
assert dt_input.value == (datetime(2018, 1, 1, 0, 0, 1), datetime(2018, 1, 3))
assert label.text == 'Datetime'
dt_input._start._process_events({'value': '2018-01-01 00:00:01a'})
assert dt_input.value == (datetime(2018, 1, 1, 0, 0, 1), datetime(2018, 1, 3))
assert label.text == 'Datetime (invalid)'
dt_input._start._process_events({'value': '2018-01-11 00:00:00'})
assert dt_input.value == (datetime(2018, 1, 1, 0, 0, 1), datetime(2018, 1, 3))
assert label.text == 'Datetime (out of bounds)'
dt_input._end._process_events({'value': '2018-01-11 00:00:00a'})
assert dt_input.value == (datetime(2018, 1, 1, 0, 0, 1), datetime(2018, 1, 3))
assert label.text == 'Datetime (out of bounds) (invalid)'
dt_input._start._process_events({'value': '2018-01-02 00:00:00'})
dt_input._end._process_events({'value': '2018-01-03 00:00:00'})
assert dt_input.value == (datetime(2018, 1, 2), datetime(2018, 1, 3))
assert label.text == 'Datetime'
dt_input._start._process_events({'value': '2018-01-05 00:00:00'})
assert dt_input.value == (datetime(2018, 1, 2), datetime(2018, 1, 3))
assert label.text == 'Datetime (start of range must be <= end)'
dt_input._start._process_events({'value': '2018-01-01 00:00:00'})
assert dt_input.value == (datetime(2018, 1, 1), datetime(2018, 1, 3))
assert label.text == 'Datetime'
def test_int_input(document, comm):
int_input = IntInput(name='Int input')
widget = int_input.get_root(document, comm=comm)
assert isinstance(widget, int_input._widget_type)
assert widget.title == 'Int input'
assert widget.step == 1
assert widget.value == 0
int_input._process_events({'value': 2})
assert int_input.value == 2
int_input._process_events({'value_throttled': 2})
assert int_input.value_throttled == 2
int_input.value = 0
assert widget.value == 0
# Testing throttled mode
with config.set(throttled=True):
int_input._process_events({'value': 1})
assert int_input.value == 0 # no change
int_input._process_events({'value_throttled': 1})
assert int_input.value == 1
int_input.value = 2
assert widget.value == 2
def test_float_input(document, comm):
float_input = FloatInput(value=0.4, name="Float input")
widget = float_input.get_root(document, comm=comm)
assert isinstance(widget, float_input._widget_type)
assert widget.title == 'Float input'
assert widget.step == 0.1
assert widget.value == 0.4
float_input._process_events({'value': 0.2})
assert float_input.value == 0.2
float_input._process_events({'value_throttled': 0.2})
assert float_input.value_throttled == 0.2
float_input.value = 0.3
assert widget.value == 0.3
# Testing throttled mode
with config.set(throttled=True):
float_input._process_events({'value': 0.4})
assert float_input.value == 0.3 # no change
float_input._process_events({'value_throttled': 0.4})
assert float_input.value == 0.4
float_input.value = 0.5
assert widget.value == 0.5
def test_array_input(document, comm):
array_input = ArrayInput(value=np.array([1, 2, 3]), name="Array input", max_array_size=3)
widget = array_input.get_root(document, comm=comm)
assert isinstance(widget, array_input._widget_type)
assert widget.title == 'Array input'
assert widget.value == '[1, 2, 3]'
assert not widget.disabled
array_input.value = np.array([1, 2, 3, 4])
assert widget.value == "'[1,2,3,4]'"
assert widget.disabled
assert array_input._auto_disabled
array_input.value = np.array([1, 2, 3])
assert not widget.disabled
assert not array_input._auto_disabled