Revision: e4d89db0312a
Author: Mikko Korpela <[email protected]>
Date: Tue Jun 21 12:33:07 2011
Log: Add ability to set mappings in json_dump and replace empty
strings in pruned strings with a one char variable
http://code.google.com/p/robotframework/source/detail?r=e4d89db0312a
Modified:
/src/robot/result/json.py
/src/robot/result/jsondatamodel.py
/src/robot/webcontent/testdata/data.js
/utest/result/test_js_serializer.py
=======================================
--- /src/robot/result/json.py Thu Jun 16 15:25:12 2011
+++ /src/robot/result/json.py Tue Jun 21 12:33:07 2011
@@ -35,7 +35,7 @@
string = string.replace('\t', '\\t')
return '"%s"' % ''.join(get_matching_char(c) for c in string)
-def json_dump(data, output):
+def json_dump(data, output, mappings=None):
if data is None:
output.write('null')
elif isinstance(data, (int, long)):
@@ -45,18 +45,20 @@
elif isinstance(data, list):
output.write('[')
for index, item in enumerate(data):
- json_dump(item, output)
+ 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)
+ json_dump(item[0], output, mappings)
output.write(':')
- json_dump(item[1], output)
+ json_dump(item[1], output, mappings)
if index < len(data)-1:
output.write(',')
output.write('}')
+ elif mappings and data in mappings:
+ output.write(mappings[data])
else:
raise Exception('Data type (%s) serialization not supported' %
type(data))
=======================================
--- /src/robot/result/jsondatamodel.py Tue Jun 21 09:45:45 2011
+++ /src/robot/result/jsondatamodel.py Tue Jun 21 12:33:07 2011
@@ -20,6 +20,8 @@
class DataModel(object):
+ UNUSED_STRING = object()
+
def __init__(self, robot_data):
self._robot_data = robot_data
self._settings = None
@@ -39,12 +41,13 @@
self._settings = settings
def write_to(self, output):
- self._dump_json('window.output = ', self._robot_data, output)
+ output.write('var u = "";\n')
+ self._dump_json('window.output = ', self._robot_data, output,
{DataModel.UNUSED_STRING:'u'})
self._dump_json('window.settings = ', self._settings, output)
- def _dump_json(self, name, data, output):
+ def _dump_json(self, name, data, output, mappings=None):
output.write(name)
- json.json_dump(data, output)
+ json.json_dump(data, output, mappings)
output.write(';\n')
def remove_keywords(self):
@@ -66,7 +69,7 @@
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 '' for
index, text in enumerate(self._robot_data['strings'])]
+ 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'])]
def _collect_used_indices(self, data, result):
=======================================
--- /src/robot/webcontent/testdata/data.js Tue Jun 21 05:48:33 2011
+++ /src/robot/webcontent/testdata/data.js Tue Jun 21 12:33:07 2011
@@ -1,2 +1,3 @@
-window.output =
{"integers":[0,-1,1,48,49,47,2,50,66,55,67,54,13,51,17,74,76,75,77,78,3,80,81,82,91,9,92,79,14,94,95,96,93,4,99,98,101,100,103,102,104,106,105,107,6,108,97,12,110,109,68,43,-59,171,5,73],"errors":[[-56,88,89]],"stats":[[{"fail":3,"label":"Critical
Tests","pass":2},{"fail":4,"label":"All
Tests","pass":2}],[{"info":"critical","links":"Title of
i1:http://1/","doc":"","label":"i1","combined":"","pass":2,"fail":4},{"info":"critical","links":"Title
of
i2:http://2/","doc":"","label":"i2","combined":"","pass":2,"fail":4},{"info":"non-critical","links":"","doc":"","label":"owner-kekkonen","combined":"","pass":0,"fail":1},{"info":"combined","links":"Title
of iX:http://X/","doc":"<b>Combined</b> tag
doc","label":"IX","combined":"i?","pass":2,"fail":4},{"info":"combined","links":"","doc":"","label":"zap","combined":"foo
& i*","pass":0,"fail":0},{"info":"","links":"","doc":"","label":"<
<","combined":"","pass":0,"fail":4},{"info":"","links":"","doc":"","label":"collections","combined":"","pass":2,"fail":0},{"info":"","links":"","doc":"","label":"default","combined":"","pass":0,"fail":3},{"info":"","links":"kuukkeli:http://google.com","doc":"","label":"force","combined":"","pass":0,"fail":4},{"info":"","links":"","doc":"","label":"t1","combined":"","pass":0,"fail":1},{"info":"","links":"","doc":"this
is <b>my bold</b>
test","label":"test","combined":"","pass":0,"fail":4}],[{"fail":4,"label":"Dir.Suite","name":"Dir.Suite","pass":2},{"fail":0,"label":"Dir.Suite.Test.Suite.1","name":"Test.Suite.1","pass":1},{"fail":0,"label":"Dir.Suite.Test.Suite.2","name":"Test.Suite.2","pass":1},{"fail":4,"label":"Dir.Suite.Tests","name":"Tests","pass":0}]],"generatedMillis":-272,"generator":"Robot
trunk 20110613 (Python 2.7.1 on win32)","generatedTimestamp":"20110621
15:48:16 GMT
+03:00","baseMillis":1308660496272,"suite":[27,86,87,1,{2:3,4:5,6:7},[12,13,0,8,9,[-1,10,9],[11,-2,-3]],[27,28,29,0,{},[24,25,0,26,0,[17,18,0,14,15,[-4,10,16],[11,-4,-1]],[17,13,0,8,19,[-5,10,20],[11,-5,-1]],[21,22,23],[11,-6,-7]],[11,-1,-8],[-3,-3,-3,-3]],[27,37,38,0,{},[24,36,0,26,0,[17,33,0,30,31,[-9,10,32],[11,-10,-1]],[17,13,0,8,34,[-11,10,35],[11,-9,-3]],[21,22,23],[11,-12,-13]],[11,-14,-15],[-3,-3,-3,-3]],[27,84,85,39,{40:7},[12,13,0,8,41,[-16,10,41],[11,-16,-1]],[24,50,0,26,0,[12,13,0,8,42,[-17,10,42],[11,-18,-3]],[17,13,0,8,43,[-19,10,43],[11,-19,-1]],[46,13,0,8,44,[-20,10,44],[11,-19,-3]],[47,48,49,22,23,24],[11,-18,-21]],[24,57,0,26,0,[12,13,0,8,42,[-22,10,42],[11,-22,-1]],[17,13,0,8,51,[-23,10,52],[11,-23,-1]],[17,13,0,8,53,[-24,10,54],[11,-23,-3]],[17,56,0,55,53,[-25,45,54],[45,-24,-26]],[46,13,0,8,44,[-27,10,44],[11,-27,-1]],[47,48,49,22,23,24],[45,-28,-29,53]],[24,59,0,26,0,[12,13,0,8,42,[-30,10,42],[11,-30,-3]],[17,13,0,8,58,[-31,10,58],[11,-31,-1]],[46,13,0,8,44,[-32,10,44],[11,-32,-1]],[47,48,49,22,23,24],[11,-33,-34]],[24,80,0,81,60,[12,13,0,8,61,[-35,10,61],[11,-36,-3]],[17,13,0,8,62,[-35,10,62],[11,-35,-3]],[17,64,0,0,0,[17,13,0,8,63,[-37,10,63],[11,-38,-3]],[11,-38,-7]],[75,76,0,0,0,[67,68,0,0,0,[17,13,0,8,65,[-39,10,66],[11,-40,-3]],[11,-40,-3]],[67,70,0,0,0,[17,13,0,8,65,[-41,10,69],[11,-41,-1]],[11,-39,-7]],[67,72,0,0,0,[17,13,0,8,65,[-42,10,71],[11,-43,-3]],[11,-43,-3]],[67,74,0,0,0,[17,13,0,8,65,[-44,10,73],[11,-42,-3]],[11,-42,-3]],[11,-40,-45]],[46,13,0,8,77,[-46,10,77],[11,-46,-1]],[47,49,22,23,78,79,24],[11,-47,-48]],[46,56,0,55,0,[-49,45,82],[45,-50,-7]],[45,-51,-52,83],[-34,-1,-21,-1]],[45,-53,-54],[-45,-7,-55,-7]],"strings":["*","eNqdzkEKwjAQheG9pxhygAS3Jca14ErwAEk7nQYTJ0wH2t7eunEhuHH9+D+eT+F+u3bepQA+wiQ4nsyk2jrnhBPrKLHiwvKwLGTCz8m7GHwScOHgc7jUSLireVdzJZil/7A9D2iJmQranqtrX5orTHzGVW17kgHNWvDfeNbtHSeWAaWDY1th5pIHIImb2c++AG8mWaA=","*Formatting","*<b>Bold</b>
and
<i>italics</i>","*Image","eNqdy8ENgzAMBdBVrAwQiyui7SyQGDdq0h85loDtK1bou7+lNKVh6RHe7n1mTsgSFdAqMaFxZ8MG321tcsA+XKF4yemxfzWQF6/ybx5+3XmDZbGZpn7SQC2Z1NYrED9/2Og45A==","*URL","*<a
href=\"http://robotframework.org\">http://robotframework.org</a>","*Logs
the given message with the given level.","*higher level suite
setup","*I","*P","*setup","*BuiltIn.Log","*Returns a list containing given
items.","*foo, bar, quux","*${list} = [u'foo', u'bar',
u'quux']","*kw","*${list} = BuiltIn.Create List","*${list}","*[u'foo',
u'bar', u'quux']","*collections","*i1","*i2","*test","*list
test","*Y","*suite","*C:\\workspace\\robotframework\\src\\robot\\webcontent\\testdata\\dir.suite\\test.suite.1.txt","*Test.Suite.1","*Creates
and returns a dictionary from the given `key_value_pairs`.","*key,
value","*${dict} = {u'key': u'value'}","*${dict} = Collections.Create
Dictionary","*${dict}","*{u'key': u'value'}","*Dictionary
test","*C:\\workspace\\robotframework\\src\\robot\\webcontent\\testdata\\dir.suite\\test.suite.2.txt","*Test.Suite.2","*Some
suite docs with links: <a
href=\"http://robotframework.org\">http://robotframework.org</a>","*home
*page*","*Suite setup","*Test Setup","*do nothing","*Test
Teardown","*F","*teardown","*<
<","*default","*force","*Simple","*<blink><b><font face=\"comic sans
ms\" size=\"42\" color=\"red\">CAN HAZ HMTL?!?!??!!?</font></b></blink>,
HTML","*<blink><b><font face=\"comic sans ms\" size=\"42\"
color=\"red\">CAN HAZ HMTL?!?!??!!?</font></b></blink>","*escape < <
<b>no bold</b>","*escape < &lt; <b>no bold</b>","*Fails
the test immediately with the given (optional)
message.","*BuiltIn.Fail","*Log HTML","*hyv\u00e4\u00e4
joulua","*Unicode","*Test doc","*in own setup","*in test","*in User
Kw","*User Kw","*Got ${i}","*Got 1","*foritem","*${i} = 1","*Got 2","*${i}
= 2","*Got 3","*${i} = 3","*Got 4","*${i} = 4","*forloop","*${i} IN [
@{list} ]","*in own
teardown","*owner-kekkonen","*t1","*Complex","*N","*AssertionError","*Suite
teardown
failed:\nAssertionError","*C:\\workspace\\robotframework\\src\\robot\\webcontent\\testdata\\dir.suite\\tests.txt","*Tests","*C:\\workspace\\robotframework\\src\\robot\\webcontent\\testdata\\dir.suite","*Dir.Suite","*E","*Invalid
syntax in
file 'C:\\workspace\\robotframework\\src\\robot\\webcontent\\testdata\\dir.suite\\tests.txt'
in table 'Settings': Test library 'p\u00f6lk\u00fc\\myLib.py' does not
exist."]};
+var u = "";
+window.output =
{"integers":[0,-1,1,10,11,9,2,15,14,16,12,4,20,19,21,22,23,3,24,26,25,27,31,28,33,32,35,34,36,38,39,40,42,41,43,44,45,5,46,37,48,47,17,-34,83,6],"errors":[[-14,88,89]],"stats":[[{"fail":3,"label":"Critical
Tests","pass":2},{"fail":4,"label":"All
Tests","pass":2}],[{"info":"critical","links":"Title of
i1:http://1/","doc":"","label":"i1","combined":"","pass":2,"fail":4},{"info":"critical","links":"Title
of
i2:http://2/","doc":"","label":"i2","combined":"","pass":2,"fail":4},{"info":"non-critical","links":"","doc":"","label":"owner-kekkonen","combined":"","pass":0,"fail":1},{"info":"combined","links":"Title
of iX:http://X/","doc":"<b>Combined</b> tag
doc","label":"IX","combined":"i?","pass":2,"fail":4},{"info":"combined","links":"","doc":"","label":"zap","combined":"foo
& i*","pass":0,"fail":0},{"info":"","links":"","doc":"","label":"<
<","combined":"","pass":0,"fail":4},{"info":"","links":"","doc":"","label":"collections","combined":"","pass":2,"fail":0},{"info":"","links":"","doc":"","label":"default","combined":"","pass":0,"fail":3},{"info":"","links":"kuukkeli:http://google.com","doc":"","label":"force","combined":"","pass":0,"fail":4},{"info":"","links":"","doc":"","label":"t1","combined":"","pass":0,"fail":1},{"info":"","links":"","doc":"this
is <b>my bold</b>
test","label":"test","combined":"","pass":0,"fail":4}],[{"fail":4,"label":"Dir.Suite","name":"Dir.Suite","pass":2},{"fail":0,"label":"Dir.Suite.Test.Suite.1","name":"Test.Suite.1","pass":1},{"fail":0,"label":"Dir.Suite.Test.Suite.2","name":"Test.Suite.2","pass":1},{"fail":4,"label":"Dir.Suite.Tests","name":"Tests","pass":0}]],"generatedMillis":-760,"generator":"Robot
trunk 20110613 (Python 2.6.5 on linux2)","generatedTimestamp":"20110621
22:20:44 GMT
+03:00","baseMillis":1308684044760,"suite":[27,86,87,1,{2:3,4:5,6:7},[12,13,0,8,9,[-1,10,9],[11,-2,-3]],[27,28,29,0,{},[24,25,0,26,0,[17,18,0,14,15,[-4,10,16],[11,-4,-1]],[17,13,0,8,19,[-5,10,20],[11,-4,-3]],[21,22,23],[11,-6,-7]],[11,-3,-5],[-3,-3,-3,-3]],[27,37,38,0,{},[24,36,0,26,0,[17,33,0,30,31,[-8,10,32],[11,-9,-3]],[17,13,0,8,34,[-10,10,35],[11,-8,-3]],[21,22,23],[11,-9,-7]],[11,-11,-12],[-3,-3,-3,-3]],[27,84,85,39,{40:7},[12,13,0,8,41,[-13,10,41],[11,-14,-3]],[24,50,0,26,0,[12,13,0,8,42,[-15,10,42],[11,-15,-1]],[17,13,0,8,43,[-16,10,43],[11,-15,-3]],[46,13,0,8,44,[-17,10,44],[11,-16,-3]],[47,48,49,22,23,24],[11,-13,-18]],[24,57,0,26,0,[12,13,0,8,42,[-19,10,42],[11,-19,-3]],[17,13,0,8,51,[-20,10,52],[11,-21,-3]],[17,13,0,8,53,[-22,10,54],[11,-22,-3]],[17,56,0,55,53,[-23,45,54],[45,-24,-18]],[46,13,0,8,44,[-25,10,44],[11,-26,-3]],[47,48,49,22,23,24],[45,-17,-4,53]],[24,59,0,26,0,[12,13,0,8,42,[-27,10,42],[11,-28,-3]],[17,13,0,8,58,[-27,10,58],[11,-27,-3]],[46,13,0,8,44,[-29,10,44],[11,-29,-3]],[47,48,49,22,23,24],[11,-28,-18]],[24,80,0,81,60,[12,13,0,8,61,[-30,10,61],[11,-30,-1]],[17,13,0,8,62,[-31,10,62],[11,-31,-1]],[17,64,0,0,0,[17,13,0,8,63,[-32,10,63],[11,-32,-3]],[11,-32,-3]],[75,76,0,0,0,[67,68,0,0,0,[17,13,0,8,65,[-33,10,66],[11,-33,-1]],[11,-34,-3]],[67,70,0,0,0,[17,13,0,8,65,[-35,10,69],[11,-35,-1]],[11,-33,-3]],[67,72,0,0,0,[17,13,0,8,65,[-36,10,71],[11,-36,-1]],[11,-36,-1]],[67,74,0,0,0,[17,13,0,8,65,[-37,10,73],[11,-37,-1]],[11,-37,-3]],[11,-34,-38]],[46,13,0,8,77,[-39,10,77],[11,-39,-1]],[47,49,22,23,78,79,24],[11,-40,-4]],[46,56,0,55,0,[-41,45,82],[45,-42,-3]],[45,-43,-23,83],[-12,-1,-18,-1]],[45,-44,-45],[-46,-7,-38,-7]],"strings":["*","eNqdzkEKwjAQheG9pxhygAS3Jca14ErwAEk7nQYTJ0wH2t7eunEhuHH9+D+eT+F+u3bepQA+wiQ4nsyk2jrnhBPrKLHiwvKwLGTCz8m7GHwScOHgc7jUSLireVdzJZil/7A9D2iJmQranqtrX5orTHzGVW17kgHNWvDfeNbtHSeWAaWDY1th5pIHIImb2c++AG8mWaA=","*Formatting","*<b>Bold</b>
and
<i>italics</i>","*Image","eNqdy8ENgzAMBdBVrAwQiyui7SyQGDdq0h85loDtK1bou7+lNKVh6RHe7n1mTsgSFdAqMaFxZ8MG321tcsA+XKF4yemxfzWQF6/ybx5+3XmDZbGZpn7SQC2Z1NYrED9/2Og45A==","*URL","*<a
href=\"http://robotframework.org\">http://robotframework.org</a>","*Logs
the given message with the given level.","*higher level suite
setup","*I","*P","*setup","*BuiltIn.Log","*Returns a list containing given
items.","*foo, bar, quux","*${list} = [u'foo', u'bar',
u'quux']","*kw","*${list} = BuiltIn.Create List","*${list}","*[u'foo',
u'bar', u'quux']","*collections","*i1","*i2","*test","*list
test","*Y","*suite","*/home/mkorpela/workspace/robot/src/robot/webcontent/testdata/dir.suite/test.suite.1.txt","*Test.Suite.1","*Creates
and returns a dictionary from the given `key_value_pairs`.","*key,
value","*${dict} = {u'key': u'value'}","*${dict} = Collections.Create
Dictionary","*${dict}","*{u'key': u'value'}","*Dictionary
test","*/home/mkorpela/workspace/robot/src/robot/webcontent/testdata/dir.suite/test.suite.2.txt","*Test.Suite.2","*Some
suite docs with links: <a
href=\"http://robotframework.org\">http://robotframework.org</a>","*home
*page*","*Suite setup","*Test Setup","*do nothing","*Test
Teardown","*F","*teardown","*<
<","*default","*force","*Simple","*<blink><b><font face=\"comic sans
ms\" size=\"42\" color=\"red\">CAN HAZ HMTL?!?!??!!?</font></b></blink>,
HTML","*<blink><b><font face=\"comic sans ms\" size=\"42\"
color=\"red\">CAN HAZ HMTL?!?!??!!?</font></b></blink>","*escape < <
<b>no bold</b>","*escape < &lt; <b>no bold</b>","*Fails
the test immediately with the given (optional)
message.","*BuiltIn.Fail","*Log HTML","*hyv\u00e4\u00e4
joulua","*Unicode","*Test doc","*in own setup","*in test","*in User
Kw","*User Kw","*Got ${i}","*Got 1","*foritem","*${i} = 1","*Got 2","*${i}
= 2","*Got 3","*${i} = 3","*Got 4","*${i} = 4","*forloop","*${i} IN [
@{list} ]","*in own
teardown","*owner-kekkonen","*t1","*Complex","*N","*AssertionError","*Suite
teardown
failed:\nAssertionError","*/home/mkorpela/workspace/robot/src/robot/webcontent/testdata/dir.suite/tests.txt","*Tests","*/home/mkorpela/workspace/robot/src/robot/webcontent/testdata/dir.suite","*Dir.Suite","*E","*Invalid
syntax in
file '/home/mkorpela/workspace/robot/src/robot/webcontent/testdata/dir.suite/tests.txt'
in table 'Settings': Test library 'p\u00f6lk\u00fc/myLib.py' does not
exist."]};
window.settings =
{"reportURL":"report.html","background":{"fail":"DeepPink"},"logURL":"log.html"};
=======================================
--- /utest/result/test_js_serializer.py Tue Jun 21 09:45:45 2011
+++ /utest/result/test_js_serializer.py Tue Jun 21 12:33:07 2011
@@ -1,6 +1,7 @@
from __future__ import with_statement
import StringIO
import time
+from robot.result.jsondatamodel import DataModel
try:
import json
@@ -244,13 +245,18 @@
def _test_remove_keywords(self, data_model):
strings_before = self._list_size(data_model._robot_data['strings'])
integers_before =
self._list_size(data_model._robot_data['integers'])
+ data_model_json_before = StringIO.StringIO()
+ data_model.write_to(data_model_json_before)
data_model.remove_keywords()
self.assert_model_does_not_contain(data_model,
['kw', 'setup', 'forloop', 'foritem'])
+ data_model_json_after = StringIO.StringIO()
+ data_model.write_to(data_model_json_after)
+ assert_true(len(data_model_json_before.getvalue()) >
len(data_model_json_after.getvalue()))
assert_true(strings_before >
self._list_size(data_model._robot_data['strings']))
assert_true(integers_before >
self._list_size(data_model._robot_data['integers']))
def _list_size(self, array):
- return len(''.join([str(val) for val in array]))
+ return len(''.join(str(val) if val != DataModel.UNUSED_STRING
else 'u' for val in array))
def test_suite_xml_parsing(self):
# Tests parsing the whole suite structure