Revision: f1afea234f73
Author: Pekka Klärck
Date: Tue Jun 21 15:04:21 2011
Log: json dump: remove strings and integers for real after removing
keywords
http://code.google.com/p/robotframework/source/detail?r=f1afea234f73
Modified:
/src/robot/result/json.py
/src/robot/result/jsondatamodel.py
/utest/result/test_js_serializer.py
=======================================
--- /src/robot/result/json.py Tue Jun 21 12:33:07 2011
+++ /src/robot/result/json.py Tue Jun 21 15:04:21 2011
@@ -35,30 +35,30 @@
string = string.replace('\t', '\\t')
return '"%s"' % ''.join(get_matching_char(c) for c in string)
-def json_dump(data, output, mappings=None):
+def json_dump(data, output, mapping=None):
if data is None:
output.write('null')
- elif isinstance(data, (int, long)):
- output.write(str(data))
- elif isinstance(data, basestring):
- output.write(encode_basestring(data))
- elif isinstance(data, list):
- output.write('[')
- for index, item in enumerate(data):
- json_dump(item, output, mappings)
- if index < len(data)-1:
- output.write(',')
- output.write(']')
elif isinstance(data, dict):
output.write('{')
- for index, item in enumerate(data.items()):
- json_dump(item[0], output, mappings)
+ for index, key in enumerate(data):
+ json_dump(key, output, mapping)
output.write(':')
- json_dump(item[1], output, mappings)
+ json_dump(data[key], output, mapping)
if index < len(data)-1:
output.write(',')
output.write('}')
- elif mappings and data in mappings:
- output.write(mappings[data])
+ elif isinstance(data, (list, tuple)):
+ output.write('[')
+ for index, item in enumerate(data):
+ json_dump(item, output, mapping)
+ if index < len(data)-1:
+ output.write(',')
+ output.write(']')
+ elif mapping and data in mapping:
+ json_dump(mapping[data], output)
+ elif isinstance(data, (int, long)):
+ output.write(str(data))
+ elif isinstance(data, basestring):
+ output.write(encode_basestring(data))
else:
raise Exception('Data type (%s) serialization not supported' %
type(data))
=======================================
--- /src/robot/result/jsondatamodel.py Tue Jun 21 13:22:00 2011
+++ /src/robot/result/jsondatamodel.py Tue Jun 21 15:04:21 2011
@@ -20,12 +20,11 @@
class DataModel(object):
- UNUSED_STRING = object()
-
def __init__(self, robot_data):
self._robot_data = robot_data
self._settings = None
self._set_generated(time.localtime())
+ self._index_remap = {}
def _set_generated(self, timetuple):
genMillis = long(time.mktime(timetuple) * 1000) -\
@@ -40,14 +39,14 @@
def set_settings(self, settings):
self._settings = settings
- def write_to(self, output):
- output.write('var u = "";\n')
- self._dump_json('window.output = ', self._robot_data, output,
{DataModel.UNUSED_STRING:'u'})
+ def write_to(self, output, mapping=None):
+ self._dump_json('window.output = ', self._robot_data, output,
+ self._index_remap)
self._dump_json('window.settings = ', self._settings, output)
- def _dump_json(self, name, data, output, mappings=None):
+ def _dump_json(self, name, data, output, mapping=None):
output.write(name)
- json.json_dump(data, output, mappings)
+ json.json_dump(data, output, mapping)
output.write(';\n')
def remove_keywords(self):
@@ -69,8 +68,22 @@
def _prune_unused_indices(self):
used = self._collect_used_indices(self._robot_data['suite'], set())
- self._robot_data['strings'] = [text if index in used else
DataModel.UNUSED_STRING for index, text in
enumerate(self._robot_data['strings'])]
- self._robot_data['integers'] = [number if (-1 -index) in used else
0 for index, number in enumerate(self._robot_data['integers'])]
+ self._robot_data['strings'] = \
+ list(self._prune(self._robot_data['strings'], used))
+ self._robot_data['integers'] = \
+ list(self._prune(self._robot_data['integers'], used,
+ map_index=lambda index: -1 - index,
+ offset_increment=-1))
+
+ def _prune(self, data, used, map_index=None, offset_increment=1):
+ offset = 0
+ for index, text in enumerate(data):
+ index = map_index(index) if map_index else index
+ if index in used:
+ self._index_remap[index] = index - offset
+ yield text
+ else:
+ offset += offset_increment
def _collect_used_indices(self, data, result):
for item in data:
=======================================
--- /utest/result/test_js_serializer.py Tue Jun 21 13:22:00 2011
+++ /utest/result/test_js_serializer.py Tue Jun 21 15:04:21 2011
@@ -18,6 +18,10 @@
from robot.result.elementhandlers import Context
from robot.utils.asserts import assert_equals, assert_true,
assert_not_equals, assert_false
+
+# TODO: Split this monster test suite.
+# At least json_dump tests should be moved to their own module.
+
class TestJsSerializer(unittest.TestCase):
SUITE_XML = """
@@ -118,8 +122,10 @@
self._assert_plain_suite(data_model, plain_suite)
def assert_model_does_not_contain(self, data_model, items):
- self._check_does_not_contain(self._reverse_from_ids(data_model,
data_model._robot_data['suite']),
- ['*'+i for i in items])
+ suite = self._reverse_from_ids(data_model,
+ data_model._robot_data['suite'],
+ data_model._index_remap)
+ self._check_does_not_contain(suite, ['*'+i for i in items])
def _check_does_not_contain(self, suite, items):
for item in suite:
@@ -131,18 +137,18 @@
reversed = self._reverse_from_ids(data_model,
data_model._robot_data['suite'])
assert_equals(reversed, plain_suite)
- def _reverse_from_ids(self, data_model, suite):
- if isinstance(suite, (int, long)):
- return self._reverse_id(data_model, suite)
- result = []
- for entry in suite:
- if isinstance(entry, list):
- result += [self._reverse_from_ids(data_model, entry)]
- elif isinstance(entry, dict):
- result += [dict((self._reverse_from_ids(data_model, key),
self._reverse_from_ids(data_model, value)) for key, value in entry.items())]
- else:
- result += [self._reverse_id(data_model, entry)]
- return result
+ def _reverse_from_ids(self, data, item, remap={}):
+ recurse = self._reverse_from_ids
+ if isinstance(item, (int, long)):
+ if item in remap:
+ item = remap[item]
+ return self._reverse_id(data, item)
+ if isinstance(item, list):
+ return [recurse(data, i, remap) for i in item]
+ if isinstance(item, dict):
+ return dict((recurse(data, k, remap),
+ recurse(data, item[k], remap)) for k in item)
+ raise AssertionError('Unexpected item %r' % item)
def _reverse_id(self, data_model, id):
if id is None:
@@ -259,7 +265,7 @@
assert_true(integers_before >
self._list_size(data_model._robot_data['integers']))
def _list_size(self, array):
- return len(''.join(str(val) if val != DataModel.UNUSED_STRING
else 'u' for val in array))
+ return len(''.join(str(val) for val in array))
def test_suite_xml_parsing(self):
# Tests parsing the whole suite structure
@@ -357,8 +363,9 @@
buffer = StringIO.StringIO()
mapped1 = object()
mapped2 = object()
- json_dump([mapped1, [mapped2, {mapped2:mapped1}]], buffer,
{mapped1:'1', mapped2:'a'})
- assert_equals('[1,[a,{a:1}]]', buffer.getvalue())
+ json_dump([mapped1, [mapped2, {mapped2:mapped1}]], buffer,
+ mapping={mapped1:'1', mapped2:'a'})
+ assert_equals('["1",["a",{"a":"1"}]]', buffer.getvalue())
def _get_data_model(self, xml_string):
sax.parseString('<robot
generator="test">%s<statistics/><errors/></robot>' % xml_string,
self._handler)