Skip to content

Commit a9911ff

Browse files
authored
Merge pull request #50 from highcharts-for-python/develop
PR for v.1.4.6
2 parents 6b72e57 + 52923e1 commit a9911ff

File tree

4 files changed

+270
-64
lines changed

4 files changed

+270
-64
lines changed

CHANGES.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
Release 1.4.6
2+
=========================================
3+
4+
* **BUGFIX**: Fixed ``FlagData`` and ``FlagDataCollection`` serialization bug (#49).
5+
6+
---------------------
7+
18
Release 1.4.5
29
=========================================
310

highcharts_stock/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.4.5'
1+
__version__ = '1.4.6'

highcharts_stock/options/series/data/flags.py

Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,6 @@ def from_list(cls, value):
5454
as_obj = cls(x = None)
5555
elif checkers.is_numeric(item):
5656
as_obj = cls(x = item)
57-
elif checkers.is_iterable(item):
58-
if len(item) == 2:
59-
as_obj = cls(x = item[0], title = item[1])
60-
elif len(item) == 1:
61-
as_obj = cls(x = item[0])
62-
else:
63-
raise errors.HighchartsValueError(f'data expects either a 1D or 2D '
64-
f'collection. Collection received '
65-
f'had {len(item)} dimensions.')
6657
else:
6758
raise errors.HighchartsValueError(f'each data point supplied must either '
6859
f'be a Flag Data Point or be '
@@ -81,55 +72,14 @@ def from_ndarray(cls, value):
8172
:rtype: :class:`DataPointCollection <highcharts_core.options.series.data.collections.DataPointCollection>`
8273
"""
8374
return FlagDataCollection.from_ndarray(value)
84-
75+
8576
@classmethod
8677
def _get_supported_dimensions(cls) -> List[int]:
8778
"""Returns a list of the supported dimensions for the data point.
8879
8980
:rtype: :class:`list <python:list>` of :class:`int <python:int>`
9081
"""
91-
return [1, 2]
92-
93-
@classmethod
94-
def _get_props_from_array(cls, length = None) -> List[str]:
95-
"""Returns a list of the property names that can be set using the
96-
:meth:`.from_array() <highcharts_core.options.series.data.base.DataBase.from_array>`
97-
method.
98-
99-
:param length: The length of the array, which may determine the properties to
100-
parse. Defaults to :obj:`None <python:None>`, which returns the full list of
101-
properties.
102-
:type length: :class:`int <python:int>` or :obj:`None <python:None>`
103-
104-
:rtype: :class:`list <python:list>` of :class:`str <python:str>`
105-
"""
106-
prop_list = {
107-
None: ['x', 'title'],
108-
1: ['x'],
109-
2: ['x', 'title']
110-
}
111-
112-
return cls._get_props_from_array_helper(prop_list, length)
113-
114-
def to_array(self, force_object = False) -> List | Dict:
115-
"""Generate the array representation of the data point (the inversion
116-
of
117-
:meth:`.from_array() <highcharts_core.options.series.data.base.DataBase.from_array>`).
118-
119-
.. warning::
120-
121-
If the data point *cannot* be serialized to a JavaScript array,
122-
this method will instead return the untrimmed :class:`dict <python:dict>`
123-
representation of the data point as a fallback.
124-
125-
:param force_object: if ``True``, forces the return of the instance's
126-
untrimmed :class:`dict <python:dict>` representation. Defaults to ``False``.
127-
:type force_object: :class:`bool <python:bool>`
128-
129-
:returns: The array representation of the data point.
130-
:rtype: :class:`list <python:list>` of values or :class:`dict <python:dict>`
131-
"""
132-
return self._to_untrimmed_dict()
82+
return [1]
13383

13484
@classmethod
13585
def _get_kwargs_from_dict(cls, as_dict):
@@ -198,17 +148,6 @@ def _to_untrimmed_dict(self, in_cls = None) -> dict:
198148

199149
class FlagDataCollection(DataPointCollection):
200150

201-
@property
202-
def requires_js_object(self) -> bool:
203-
"""Indicates whether or not the data point *must* be serialized to a JS literal
204-
object or whether it can be serialized to a primitive array.
205-
206-
:returns: ``True`` if the data point *must* be serialized to a JS literal object.
207-
``False`` if it can be serialized to an array.
208-
:rtype: :class:`bool <python:bool>`
209-
"""
210-
return True
211-
212151
@classmethod
213152
def _get_data_point_class(cls):
214153
"""The Python class to use as the underlying data point within the Collection.
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
"""Tests for ``highcharts.no_data``."""
2+
3+
import pytest
4+
5+
from json.decoder import JSONDecodeError
6+
7+
from highcharts_stock.options.series.data.flags import FlagData as cls4
8+
from highcharts_stock import errors
9+
from tests.fixtures import input_files, check_input_file, to_camelCase, to_js_dict, \
10+
Class__init__, Class__to_untrimmed_dict, Class_from_dict, Class_to_dict, \
11+
Class_from_js_literal
12+
13+
STANDARD_PARAMS_4 = [
14+
({}, None),
15+
({
16+
'title': 'Test Title',
17+
'x': 123,
18+
19+
'data_labels': {
20+
'align': 'center',
21+
'allowOverlap': True,
22+
'animation': {
23+
'defer': 5
24+
},
25+
'backgroundColor': {
26+
'linearGradient': {
27+
'x1': 0.123,
28+
'x2': 0.234,
29+
'y1': 0.345,
30+
'y2': 0.456
31+
},
32+
'stops': [
33+
[0.12, '#999'],
34+
[0.34, '#fff']
35+
]
36+
},
37+
'borderColor': '#999999',
38+
'borderRadius': 24,
39+
'borderWidth': 1,
40+
'className': 'some-class-name',
41+
'color': '#000000',
42+
'crop': True,
43+
'defer': False,
44+
'enabled': True,
45+
'filter': {
46+
'operator': '>=',
47+
'property': 'some_property',
48+
'value': 123
49+
},
50+
'format': 'some format',
51+
'formatter': """function() { return true; }""",
52+
'inside': True,
53+
'nullFormat': 'some format',
54+
'nullFormatter': """function() { return true; }""",
55+
'overflow': 'none',
56+
'padding': 12,
57+
'position': 'center',
58+
'rotation': 0,
59+
'shadow': False,
60+
'shape': 'rect',
61+
'style': 'style goes here',
62+
'useHTML': False,
63+
'verticalAlign': 'top',
64+
'x': 10,
65+
'y': 20,
66+
'z': 0
67+
},
68+
'drag_drop': {
69+
'draggableX': True,
70+
'draggableY': True,
71+
'dragHandle': {
72+
'className': 'draghandle-classname-goes-here',
73+
'color': '#ccc',
74+
'cursor': 'alias',
75+
'lineColor': '#ddd',
76+
'lineWidth': 2,
77+
'pathFormatter': """function() { return true; }""",
78+
'zIndex': 10
79+
},
80+
'dragMaxX': 3456,
81+
'dragMaxY': 6532,
82+
'dragMinX': 123,
83+
'dragMinY': 321,
84+
'dragPrecisionX': 5,
85+
'dragPrecisionY': 5,
86+
'dragSensitivity': 2,
87+
'groupBy': 'some-property-name',
88+
'guideBox': {
89+
'default': {
90+
'className': 'some-classname-goes-here',
91+
'color': '#999',
92+
'cursor': 'pointer',
93+
'lineColor': '#ccc',
94+
'lineWidth': 2,
95+
'zIndex': 100
96+
}
97+
},
98+
'liveRedraw': True
99+
},
100+
'drilldown': 'some-id-goes-here'
101+
}, None),
102+
# + DataBase
103+
({
104+
'title': 'test title',
105+
'x': 123,
106+
107+
'data_labels': {
108+
'align': 'center',
109+
'allowOverlap': True,
110+
'animation': {
111+
'defer': 5
112+
},
113+
'backgroundColor': {
114+
'linearGradient': {
115+
'x1': 0.123,
116+
'x2': 0.234,
117+
'y1': 0.345,
118+
'y2': 0.456
119+
},
120+
'stops': [
121+
[0.12, '#999'],
122+
[0.34, '#fff']
123+
]
124+
},
125+
'borderColor': '#999999',
126+
'borderRadius': 24,
127+
'borderWidth': 1,
128+
'className': 'some-class-name',
129+
'color': '#000000',
130+
'crop': True,
131+
'defer': False,
132+
'enabled': True,
133+
'filter': {
134+
'operator': '>=',
135+
'property': 'some_property',
136+
'value': 123
137+
},
138+
'format': 'some format',
139+
'formatter': """function() { return true; }""",
140+
'inside': True,
141+
'nullFormat': 'some format',
142+
'nullFormatter': """function() { return true; }""",
143+
'overflow': 'none',
144+
'padding': 12,
145+
'position': 'center',
146+
'rotation': 0,
147+
'shadow': False,
148+
'shape': 'rect',
149+
'style': 'style goes here',
150+
'useHTML': False,
151+
'verticalAlign': 'top',
152+
'x': 10,
153+
'y': 20,
154+
'z': 0
155+
},
156+
'drag_drop': {
157+
'draggableX': True,
158+
'draggableY': True,
159+
'dragHandle': {
160+
'className': 'draghandle-classname-goes-here',
161+
'color': '#ccc',
162+
'cursor': 'alias',
163+
'lineColor': '#ddd',
164+
'lineWidth': 2,
165+
'pathFormatter': """function() { return true; }""",
166+
'zIndex': 10
167+
},
168+
'dragMaxX': 3456,
169+
'dragMaxY': 6532,
170+
'dragMinX': 123,
171+
'dragMinY': 321,
172+
'dragPrecisionX': 5,
173+
'dragPrecisionY': 5,
174+
'dragSensitivity': 2,
175+
'groupBy': 'some-property-name',
176+
'guideBox': {
177+
'default': {
178+
'className': 'some-classname-goes-here',
179+
'color': '#999',
180+
'cursor': 'pointer',
181+
'lineColor': '#ccc',
182+
'lineWidth': 2,
183+
'zIndex': 100
184+
}
185+
},
186+
'liveRedraw': True
187+
},
188+
'drilldown': 'some-id-goes-here',
189+
190+
'accessibility': {
191+
'description': 'Some description goes here',
192+
'enabled': True
193+
},
194+
'class_name': 'some-class-name',
195+
'color': '#ccc',
196+
'color_index': 2,
197+
'custom': {
198+
'some_key': 123,
199+
'other_key': 456
200+
},
201+
'description': 'Some description goes here',
202+
'events': {
203+
'click': """function(event) { return true; }""",
204+
'drag': """function(event) { return true; }""",
205+
'drop': """function(event) { return true; }""",
206+
'mouseOut': """function(event) { return true; }"""
207+
},
208+
'id': 'some-id-goes-here',
209+
'label_rank': 3,
210+
'name': 'Some Name Goes here',
211+
'selected': False
212+
}, None),
213+
]
214+
215+
216+
@pytest.mark.parametrize('kwargs, error', STANDARD_PARAMS_4)
217+
def test_FlagData__init__(kwargs, error):
218+
Class__init__(cls4, kwargs, error)
219+
220+
221+
@pytest.mark.parametrize('kwargs, error', STANDARD_PARAMS_4)
222+
def test_FlagData__to_untrimmed_dict(kwargs, error):
223+
Class__to_untrimmed_dict(cls4, kwargs, error)
224+
225+
226+
@pytest.mark.parametrize('kwargs, error', STANDARD_PARAMS_4)
227+
def test_FlagData_from_dict(kwargs, error):
228+
Class_from_dict(cls4, kwargs, error)
229+
230+
231+
@pytest.mark.parametrize('kwargs, error', STANDARD_PARAMS_4)
232+
def test_FlagData_to_dict(kwargs, error):
233+
Class_to_dict(cls4, kwargs, error)
234+
235+
236+
@pytest.mark.parametrize('filename, as_file, error', [
237+
('series/data/single_point/04.js', False, None),
238+
239+
('series/data/single_point/error-04.js',
240+
False,
241+
(errors.HighchartsValueError,
242+
errors.HighchartsParseError,
243+
JSONDecodeError,
244+
TypeError,
245+
ValueError)),
246+
247+
('series/data/single_point/04.js', True, None),
248+
249+
('series/data/single_point/error-04.js',
250+
True,
251+
(errors.HighchartsValueError,
252+
errors.HighchartsParseError,
253+
JSONDecodeError,
254+
TypeError,
255+
ValueError)),
256+
257+
])
258+
def test_FlagData_from_js_literal(input_files, filename, as_file, error):
259+
Class_from_js_literal(cls4, input_files, filename, as_file, error)
260+

0 commit comments

Comments
 (0)