Skip to content

Commit

Permalink
Merge pull request #292 from open-craft/ekolpakov/unicode-serialization
Browse files Browse the repository at this point in the history
Fixed exporting List and Dict with unicode contents
  • Loading branch information
e-kolpakov committed Apr 3, 2015
2 parents d47ba5c + 496d3cb commit aed464a
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 2 deletions.
5 changes: 3 additions & 2 deletions xblock/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,13 +453,14 @@ def _add_field(self, node, field_name, field):
Depending on settings, it either stores the value of field
as an xml attribute or creates a separate child node.
"""
value = field.to_string(field.read_from(self))
if field.xml_node:
tag = etree.QName(XML_NAMESPACES["option"], field_name)
elem = node.makeelement(tag)
elem.text = field.to_string(field.read_from(self))
elem.text = value
node.insert(0, elem)
else:
node.set(field_name, unicode(field.read_from(self)))
node.set(field_name, value)


class IndexInfoMixin(object):
Expand Down
105 changes: 105 additions & 0 deletions xblock/test/test_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,111 @@ def test_unknown_field_as_node_raises_warning(self, parameter_name):
patched_warn.assert_called_once_with("XBlock %s does not contain field %s", type(block), parameter_name)


class TestRoundTrip(XmlTest, unittest.TestCase):
""" Test serialization-deserialization sequence """

def create_block(self, block_type):
"""
Create a block
"""
def_id = self.runtime.id_generator.create_definition(block_type)
usage_id = self.runtime.id_generator.create_usage(def_id)
block = self.runtime.get_block(usage_id)
return block

@XBlock.register_temp_plugin(LeafWithDictAndList)
def test_string_roundtrip(self):
""" Test correctly serializes-deserializes List and Dicts with plain string contents """
block = self.create_block("leafwithdictandlist")

expected_seq = ['1', '2']
expected_dict = {'1': '1', 'ping': 'ack'}
block.sequence = expected_seq
block.dictionary = expected_dict
xml = self.export_xml_for_block(block)

parsed = self.parse_xml_to_block(xml)

self.assertEqual(parsed.sequence, expected_seq)
self.assertEqual(parsed.dictionary, expected_dict)

@XBlock.register_temp_plugin(LeafWithDictAndList)
def test_unicode_roundtrip(self):
""" Test correctly serializes-deserializes List and Dicts with unicode contents """
block = self.create_block("leafwithdictandlist")

expected_seq = [u'1', u'2']
expected_dict = {u'1': u'1', u'ping': u'ack'}
block.sequence = expected_seq
block.dictionary = expected_dict
xml = self.export_xml_for_block(block)

parsed = self.parse_xml_to_block(xml)

self.assertEqual(parsed.sequence, expected_seq)
self.assertEqual(parsed.dictionary, expected_dict)

@XBlock.register_temp_plugin(LeafWithDictAndList)
def test_integers_roundtrip(self):
""" Test correctly serializes-deserializes List and Dicts with integer contents """
block = self.create_block("leafwithdictandlist")

expected_seq = [1, 2, 3]
expected_dict = {1: 10, 2: 20}
block.sequence = expected_seq
block.dictionary = expected_dict
xml = self.export_xml_for_block(block)
parsed = self.parse_xml_to_block(xml)

self.assertEqual(parsed.sequence, expected_seq)
self.assertNotEqual(parsed.dictionary, expected_dict)
self.assertEqual(parsed.dictionary, {str(key): value for key, value in expected_dict.items()})

@XBlock.register_temp_plugin(LeafWithDictAndList)
def test_none_contents_roundtrip(self):
""" Test correctly serializes-deserializes List and Dicts with keys/values of None """
block = self.create_block("leafwithdictandlist")

expected_seq = [1, None, 3, None]
expected_dict = {"1": None, None: 20}
block.sequence = expected_seq
block.dictionary = expected_dict
xml = self.export_xml_for_block(block)
parsed = self.parse_xml_to_block(xml)

self.assertEqual(parsed.sequence, expected_seq)
self.assertNotEqual(parsed.dictionary, expected_dict)
self.assertEqual(parsed.dictionary, {"1": None, 'null': 20})

@XBlock.register_temp_plugin(LeafWithDictAndList)
def test_none_roundtrip(self):
""" Test correctly serializes-deserializes Null List and Dict fields """
block = self.create_block("leafwithdictandlist")

block.sequence = None
block.dictionary = None
xml = self.export_xml_for_block(block)
parsed = self.parse_xml_to_block(xml)

self.assertIsNone(parsed.sequence)
self.assertIsNone(parsed.dictionary)

@XBlock.register_temp_plugin(LeafWithDictAndList)
def test_nested_roundtrip(self):
""" Test correctly serializes-deserializes nested List and Dict fields """
block = self.create_block("leafwithdictandlist")

expected_seq = [[1, 2], ["3", "4"], {"1": "2"}]
expected_dict = {"outer1": {"inner1": "1", "inner2": 2}, "outer2": [1, 2, 3]}
block.sequence = expected_seq
block.dictionary = expected_dict
xml = self.export_xml_for_block(block)
parsed = self.parse_xml_to_block(xml)

self.assertEqual(parsed.sequence, expected_seq)
self.assertEqual(parsed.dictionary, expected_dict)


def squish(text):
"""Turn any run of whitespace into one space."""
return re.sub(r"\s+", " ", text)

0 comments on commit aed464a

Please sign in to comment.