Skip to content

Commit 9348529

Browse files
committed
Fixed over-eager trimming of None data values when serializing to JSON for export. Closes #168.
1 parent 2bbc02c commit 9348529

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

highcharts_core/constants.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,39 @@ def __repr__(self):
953953
]
954954

955955

956+
ALLOWED_NONE_CONTEXTS = [
957+
"CartesianData.y",
958+
"Cartesian3DData.y",
959+
"Cartesian3DData.z",
960+
"CartesianValueData.value",
961+
"BarData.y",
962+
"WaterfallData.y",
963+
"WindBarbData.y",
964+
"WindBarbData.value",
965+
"XRangeData.y",
966+
"BoxPlotData.low",
967+
"BoxPlotData.high",
968+
"BoxPlotData.median",
969+
"BoxPlotData.q1",
970+
"BoxPlotData.q3",
971+
"VariablePieData.z",
972+
"RangeData.low",
973+
"RangeData.high",
974+
975+
"HLCData.high",
976+
"HLCData.low",
977+
"HLCData.close",
978+
"OHLCData.open",
979+
"OHLCData.high",
980+
"OHLCData.low",
981+
"OHLCData.close",
982+
"CandlestickData.open",
983+
"CandlestickData.high",
984+
"CandlestickData.low",
985+
"CandlestickData.close",
986+
]
987+
988+
956989
DATA_COLUMN_TYPES = [
957990
'string',
958991
'number',

highcharts_core/metaclasses.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,9 @@ def trim_dict(untrimmed: dict,
365365
# other falsy -> str, but empty string is allowed
366366
elif value == '' and context_key in constants.EMPTY_STRING_CONTEXTS:
367367
as_dict[key] = ''
368+
elif value is None and context_key in constants.ALLOWED_NONE_CONTEXTS:
369+
if to_json:
370+
as_dict[key] = None
368371

369372
return as_dict
370373

tests/fixtures.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
from highcharts_core import constants
2525

2626

27+
ALLOWED_NONE_PROPERTIES = []
28+
for item in constants.ALLOWED_NONE_CONTEXTS:
29+
class_name, prop_name = item.split('.')
30+
if prop_name not in ALLOWED_NONE_PROPERTIES:
31+
ALLOWED_NONE_PROPERTIES.append(prop_name)
32+
33+
2734
class State(object):
2835
"""Class to hold incremental test state."""
2936
# pylint: disable=too-few-public-methods
@@ -241,12 +248,26 @@ def does_kwarg_value_match_result(kwarg_value, result_value):
241248
print('- checking two dict objects')
242249
if len(kwarg_value) != len(result_value):
243250
print('-- len does not match')
244-
return False
251+
if len(kwarg_value) > len(result_value):
252+
extra_in_result = [x for x in result_value if x not in kwarg_value]
253+
extra_in_kwarg = [x for x in kwarg_value if x not in result_value]
254+
print(f'-- extra in RESULT: {extra_in_result}')
255+
print(f'-- extra in KWARG: {extra_in_kwarg}')
256+
return False
257+
difference = len(result_value) - len(kwarg_value)
258+
if abs(difference) > 1:
259+
return False
245260
for key in kwarg_value:
246261
print(f'CHECKING: {key}')
247262
if key == 'patternOptions':
248263
matches = does_kwarg_value_match_result(kwarg_value.get(key),
249264
result_value.get('pattern'))
265+
elif key in ALLOWED_NONE_PROPERTIES:
266+
if kwarg_value.get(key, None) is None and result_value.get(key) is None:
267+
continue
268+
else:
269+
matches = does_kwarg_value_match_result(kwarg_value.get(key),
270+
result_value.get(key))
250271
else:
251272
matches = does_kwarg_value_match_result(kwarg_value.get(key),
252273
result_value.get(key))
@@ -303,7 +324,7 @@ def trim_expected_dict(expected):
303324
if not isinstance(expected, dict):
304325
return expected
305326
for key in expected:
306-
if expected[key] is None:
327+
if expected[key] is None and key not in ALLOWED_NONE_PROPERTIES:
307328
continue
308329
elif isinstance(expected[key], dict):
309330
trimmed_value = trim_expected_dict(expected[key])

0 commit comments

Comments
 (0)