Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@

Release 1.5.1
=========================================

* **BUGFIX:** Fixed bug in JS literal serialization that would misinterpret strings that
start with ``{``, end with ``}``, and contain a colon (``:``) as an object literal rather
than as a string. (#130)

--------------------

Release 1.5.0
=========================================

Expand Down
2 changes: 1 addition & 1 deletion highcharts_core/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.5.0'
__version__ = '1.5.1'
26 changes: 19 additions & 7 deletions highcharts_core/js_literal_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,25 @@ def is_js_object(as_str, careful_validation = False):
is_empty = as_str[1:-1].strip() == ''
if is_empty:
return True
has_colon = ':' in as_str
if has_colon:
return True
if 'new ' in as_str:
colon_count = as_str.count(':')
open_brace_count = as_str.count('{')
close_brace_count = as_str.count('}')
brace_set_count = (open_brace_count + close_brace_count) / 2
if colon_count > 0:
if brace_set_count == 1:
return True
elif brace_set_count > 1 and colon_count >= brace_set_count:
return True
else:
careful_validation = True
elif 'new ' in as_str:
return True
if 'Object.create(' in as_str:
elif 'Object.create(' in as_str:
return True
return False
else:
else:
return False

if careful_validation:
expression_item = f'const testName = {as_str}'
try:
parsed = esprima.parseScript(expression_item)
Expand All @@ -192,6 +202,8 @@ def is_js_object(as_str, careful_validation = False):
return True

return False

return False


def attempt_variable_declaration(as_str):
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@ def Class_from_js_literal(cls, input_files, filename, as_file, error):
assert isinstance(result, cls) is True

as_js_literal = result.to_js_literal()
print(as_js_literal)
#print('-----------------')
#print('RESULT VALIDATION')
if 'pattern:' in as_js_literal:
Expand Down
19 changes: 18 additions & 1 deletion tests/options/test_tooltips.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from highcharts_core import errors
from tests.fixtures import input_files, check_input_file, to_camelCase, to_js_dict, \
Class__init__, Class__to_untrimmed_dict, Class_from_dict, Class_to_dict, \
Class_from_js_literal
Class_from_js_literal, compare_js_literals

STANDARD_PARAMS = [
({}, None),
Expand Down Expand Up @@ -86,6 +86,9 @@
}""",
'split': True
}, None),
({
'format': '{point.name} {point.y}'
}, None),

({
'border_width': 'not-a-number'
Expand Down Expand Up @@ -128,3 +131,17 @@ def test_to_dict(kwargs, error):
])
def test_from_js_literal(input_files, filename, as_file, error):
Class_from_js_literal(cls, input_files, filename, as_file, error)


def test_bug130_tooltip_serialization():
as_js_literal = """{
format: '{point.name}: {point.y}'
}"""

obj = cls.from_js_literal(as_js_literal)
assert obj is not None
assert isinstance(obj, cls) is True
assert obj.format == '{point.name}: {point.y}'

result = obj.to_js_literal()
assert "'{point.name}: {point.y}'" in result or '"{point.name}: {point.y}"' in result
18 changes: 18 additions & 0 deletions tests/test_js_literal_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,21 @@ def test_convert_js_property_to_python(original_str, override, expected, error):
else:
with pytest.raises(error):
result = js.convert_js_property_to_python(item, original_str)


@pytest.mark.parametrize('original_str, expected, error', [
("Object.create({item1:true})", True, None),
("new Date()", True, None),
("test string", False, None),
("{item1: 456}", True, None),
("'{point.name}: {point.y}'", False, None),
("{item: {subitem: 123}}", True, None),
("{item: 123, item2: 456, item3: {subitem: 789}}", True, None),
])
def test_is_js_object(original_str, expected, error):
if not error:
result = js.is_js_object(original_str)
assert result is expected
else:
with pytest.raises(error):
result = js.is_js_object(original_str)