1#-----------------------------------------------------------------------------
2# Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors.
3# All rights reserved.
4#
5# The full license is in the file LICENSE.txt, distributed with this software.
6#-----------------------------------------------------------------------------
7
8#-----------------------------------------------------------------------------
9# Boilerplate
10#-----------------------------------------------------------------------------
11import pytest ; pytest
12
13#-----------------------------------------------------------------------------
14# Imports
15#-----------------------------------------------------------------------------
16
17# Bokeh imports
18from bokeh._testing.util.api import verify_all
19from bokeh.models import (
20    CategoricalColorMapper,
21    CategoricalMarkerMapper,
22    CategoricalPatternMapper,
23    CumSum,
24    Dodge,
25    FactorRange,
26    Jitter,
27    LinearColorMapper,
28    LogColorMapper,
29    Stack,
30)
31
32# Module under test
33import bokeh.transform as bt # isort:skip
34
35#-----------------------------------------------------------------------------
36# Setup
37#-----------------------------------------------------------------------------
38
39ALL = (
40    'cumsum',
41    'dodge',
42    'factor_cmap',
43    'factor_hatch',
44    'factor_mark',
45    'jitter',
46    'linear_cmap',
47    'log_cmap',
48    'stack',
49    'transform',
50)
51
52#-----------------------------------------------------------------------------
53# General API
54#-----------------------------------------------------------------------------
55
56Test___all__ = verify_all(bt, ALL)
57
58
59class Test_cumsum:
60    def test_basic(object) -> None:
61        s = bt.cumsum("foo")
62        assert isinstance(s, dict)
63        assert list(s.keys()) == ["expr"]
64        assert isinstance(s['expr'], CumSum)
65        assert s['expr'].field == 'foo'
66        assert s['expr'].include_zero == False
67
68    def test_include_zero(object) -> None:
69        s = bt.cumsum("foo", include_zero=True)
70        assert isinstance(s, dict)
71        assert list(s.keys()) == ["expr"]
72        assert isinstance(s['expr'], CumSum)
73        assert s['expr'].field == 'foo'
74        assert s['expr'].include_zero == True
75
76
77class Test_dodge:
78    def test_basic(self) -> None:
79        t = bt.dodge("foo", 0.5)
80        assert isinstance(t, dict)
81        assert set(t) == {"field", "transform"}
82        assert t['field'] == "foo"
83        assert isinstance(t['transform'], Dodge)
84        assert t['transform'].value == 0.5
85        assert t['transform'].range is None
86
87    def test_with_range(self) -> None:
88        r = FactorRange("a")
89        t = bt.dodge("foo", 0.5, range=r)
90        assert isinstance(t, dict)
91        assert set(t) == {"field", "transform"}
92        assert t['field'] == "foo"
93        assert isinstance(t['transform'], Dodge)
94        assert t['transform'].value == 0.5
95        assert t['transform'].range is r
96        assert t['transform'].range.factors == ["a"]
97
98
99class Test_factor_cmap:
100    def test_basic(self) -> None:
101        t = bt.factor_cmap("foo", ["red", "green"], ["foo", "bar"], start=1, end=2, nan_color="pink")
102        assert isinstance(t, dict)
103        assert set(t) == {"field", "transform"}
104        assert t['field'] == "foo"
105        assert isinstance(t['transform'], CategoricalColorMapper)
106        assert t['transform'].palette == ["red", "green"]
107        assert t['transform'].factors == ["foo", "bar"]
108        assert t['transform'].start == 1
109        assert t['transform'].end == 2
110        assert t['transform'].nan_color == "pink"
111
112    def test_defaults(self) -> None:
113        t = bt.factor_cmap("foo", ["red", "green"], ["foo", "bar"])
114        assert isinstance(t, dict)
115        assert set(t) == {"field", "transform"}
116        assert t['field'] == "foo"
117        assert isinstance(t['transform'], CategoricalColorMapper)
118        assert t['transform'].palette == ["red", "green"]
119        assert t['transform'].factors == ["foo", "bar"]
120        assert t['transform'].start == 0
121        assert t['transform'].end is None
122        assert t['transform'].nan_color == "gray"
123
124
125class Test_factor_hatch:
126    def test_basic(self) -> None:
127        t = bt.factor_hatch("foo", ["+", "-"], ["foo", "bar"], start=1, end=2)
128        assert isinstance(t, dict)
129        assert set(t) == {"field", "transform"}
130        assert t['field'] == "foo"
131        assert isinstance(t['transform'], CategoricalPatternMapper)
132        assert t['transform'].patterns == ["+", "-"]
133        assert t['transform'].factors == ["foo", "bar"]
134        assert t['transform'].start == 1
135        assert t['transform'].end == 2
136
137    def test_defaults(self) -> None:
138        t = bt.factor_hatch("foo", ["+", "-"], ["foo", "bar"])
139        assert isinstance(t, dict)
140        assert set(t) == {"field", "transform"}
141        assert t['field'] == "foo"
142        assert isinstance(t['transform'], CategoricalPatternMapper)
143        assert t['transform'].patterns == ["+", "-"]
144        assert t['transform'].factors == ["foo", "bar"]
145        assert t['transform'].start == 0
146        assert t['transform'].end is None
147
148
149class Test_factor_mark:
150    def test_basic(self) -> None:
151        t = bt.factor_mark("foo", ["hex", "square"], ["foo", "bar"], start=1, end=2)
152        assert isinstance(t, dict)
153        assert set(t) == {"field", "transform"}
154        assert t['field'] == "foo"
155        assert isinstance(t['transform'], CategoricalMarkerMapper)
156        assert t['transform'].markers == ["hex", "square"]
157        assert t['transform'].factors == ["foo", "bar"]
158        assert t['transform'].start == 1
159        assert t['transform'].end == 2
160
161    def test_defaults(self) -> None:
162        t = bt.factor_mark("foo", ["hex", "square"], ["foo", "bar"])
163        assert isinstance(t, dict)
164        assert set(t) == {"field", "transform"}
165        assert t['field'] == "foo"
166        assert isinstance(t['transform'], CategoricalMarkerMapper)
167        assert t['transform'].markers == ["hex", "square"]
168        assert t['transform'].factors == ["foo", "bar"]
169        assert t['transform'].start == 0
170        assert t['transform'].end is None
171
172
173class Test_jitter:
174    def test_basic(self) -> None:
175        t = bt.jitter("foo", width=0.5, mean=0.1, distribution="normal")
176        assert isinstance(t, dict)
177        assert set(t) == {"field", "transform"}
178        assert t['field'] == "foo"
179        assert isinstance(t['transform'], Jitter)
180        assert t['transform'].width == 0.5
181        assert t['transform'].mean == 0.1
182        assert t['transform'].distribution == "normal"
183        assert t['transform'].range is None
184
185    def test_defaults(self) -> None:
186        t = bt.jitter("foo", width=0.5)
187        assert isinstance(t, dict)
188        assert set(t) == {"field", "transform"}
189        assert t['field'] == "foo"
190        assert isinstance(t['transform'], Jitter)
191        assert t['transform'].width == 0.5
192        assert t['transform'].mean == 0
193        assert t['transform'].distribution == "uniform"
194        assert t['transform'].range is None
195
196    def test_with_range(self) -> None:
197        r = FactorRange("a")
198        t = bt.jitter("foo", width=0.5, mean=0.1, range=r)
199        assert isinstance(t, dict)
200        assert set(t) == {"field", "transform"}
201        assert t['field'] == "foo"
202        assert isinstance(t['transform'], Jitter)
203        assert t['transform'].width == 0.5
204        assert t['transform'].mean == 0.1
205        assert t['transform'].distribution == "uniform"
206        assert t['transform'].range is r
207        assert t['transform'].range.factors == ["a"]
208
209
210class Test_linear_cmap:
211    def test_basic(self) -> None:
212        t = bt.linear_cmap("foo", ["red", "green"], 0, 10, low_color="orange", high_color="blue", nan_color="pink")
213        assert isinstance(t, dict)
214        assert set(t) == {"field", "transform"}
215        assert t['field'] == "foo"
216        assert isinstance(t['transform'], LinearColorMapper)
217        assert t['transform'].palette == ["red", "green"]
218        assert t['transform'].low == 0
219        assert t['transform'].high == 10
220        assert t['transform'].low_color == "orange"
221        assert t['transform'].high_color == "blue"
222        assert t['transform'].nan_color == "pink"
223
224    def test_defaults(self) -> None:
225        t = bt.linear_cmap("foo", ["red", "green"], 0, 10)
226        assert isinstance(t, dict)
227        assert set(t) == {"field", "transform"}
228        assert t['field'] == "foo"
229        assert isinstance(t['transform'], LinearColorMapper)
230        assert t['transform'].palette == ["red", "green"]
231        assert t['transform'].low == 0
232        assert t['transform'].high == 10
233        assert t['transform'].low_color is None
234        assert t['transform'].high_color is None
235        assert t['transform'].nan_color == "gray"
236
237
238class Test_log_cmap:
239    def test_basic(self) -> None:
240        t = bt.log_cmap("foo", ["red", "green"], 0, 10, low_color="orange", high_color="blue", nan_color="pink")
241        assert isinstance(t, dict)
242        assert set(t) == {"field", "transform"}
243        assert t['field'] == "foo"
244        assert isinstance(t['transform'], LogColorMapper)
245        assert t['transform'].palette == ["red", "green"]
246        assert t['transform'].low == 0
247        assert t['transform'].high == 10
248        assert t['transform'].low_color == "orange"
249        assert t['transform'].high_color == "blue"
250        assert t['transform'].nan_color == "pink"
251
252    def test_defaults(self) -> None:
253        t = bt.log_cmap("foo", ["red", "green"], 0, 10)
254        assert isinstance(t, dict)
255        assert set(t) == {"field", "transform"}
256        assert t['field'] == "foo"
257        assert isinstance(t['transform'], LogColorMapper)
258        assert t['transform'].palette == ["red", "green"]
259        assert t['transform'].low == 0
260        assert t['transform'].high == 10
261        assert t['transform'].low_color is None
262        assert t['transform'].high_color is None
263        assert t['transform'].nan_color == "gray"
264
265
266class Test_stack:
267    def test_basic(object) -> None:
268        s = bt.stack("foo", "junk")
269        assert isinstance(s, dict)
270        assert list(s.keys()) == ["expr"]
271        assert isinstance(s['expr'], Stack)
272        assert s['expr'].fields == ('foo', 'junk')
273
274
275class Test_transform:
276    def test_basic(object) -> None:
277        t = bt.transform("foo", "junk")
278        assert t == dict(field="foo", transform="junk")
279
280#-----------------------------------------------------------------------------
281# Dev API
282#-----------------------------------------------------------------------------
283
284#-----------------------------------------------------------------------------
285# Private API
286#-----------------------------------------------------------------------------
287
288#-----------------------------------------------------------------------------
289# Code
290#-----------------------------------------------------------------------------
291