4 new revisions:

Revision: 9e6b0a81f43e
Author:   Janne Härkönen <[email protected]>
Date:     Wed Jun 15 02:33:16 2011
Log:      Fix test after API change
http://code.google.com/p/robotframework/source/detail?r=9e6b0a81f43e

Revision: 174034b21137
Author:   Janne Härkönen <[email protected]>
Date:     Wed Jun 15 03:39:31 2011
Log:      Fixed comment syntax in CSS
http://code.google.com/p/robotframework/source/detail?r=174034b21137

Revision: 8447b3e58bce
Author:   Janne Härkönen <[email protected]>
Date:     Wed Jun 15 03:41:12 2011
Log:      serializing: write settings as separate JSON object
http://code.google.com/p/robotframework/source/detail?r=8447b3e58bce

Revision: 65019c59d464
Author:   Janne Härkönen <[email protected]>
Date:     Wed Jun 15 03:41:24 2011
Log:      merge
http://code.google.com/p/robotframework/source/detail?r=65019c59d464

==============================================================================
Revision: 9e6b0a81f43e
Author:   Janne Härkönen <[email protected]>
Date:     Wed Jun 15 02:33:16 2011
Log:      Fix test after API change
http://code.google.com/p/robotframework/source/detail?r=9e6b0a81f43e

Modified:
 /utest/serializing/test_reporting.py

=======================================
--- /utest/serializing/test_reporting.py        Tue Jun 14 23:56:15 2011
+++ /utest/serializing/test_reporting.py        Wed Jun 15 02:33:16 2011
@@ -17,10 +17,9 @@

 def set_serialize_report_mock():
     results = {'report_path':None}
- def serialize_report(test_output_datamodel, report_path, title=None, background=None, logpath=None): + def serialize_report(test_output_datamodel, report_path, title=None, logpath=None):
         results['report_path'] = report_path
         results['title'] = title
-        results['background'] = background
         results['logpath'] = logpath
     robot.serializing.testoutput.serialize_report = serialize_report
     return results

==============================================================================
Revision: 174034b21137
Author:   Janne Härkönen <[email protected]>
Date:     Wed Jun 15 03:39:31 2011
Log:      Fixed comment syntax in CSS
http://code.google.com/p/robotframework/source/detail?r=174034b21137

Modified:
 /src/robot/webcontent/common.css

=======================================
--- /src/robot/webcontent/common.css    Tue Jun 14 23:23:59 2011
+++ /src/robot/webcontent/common.css    Wed Jun 15 03:39:31 2011
@@ -138,7 +138,8 @@
 }

 #generated {
-/ / TODO : Add width when timestamp in correct format / / width : 29 %;
+    /* TODO : Add width when timestamp in correct format
+    width : 29 %; */
     float: right;
     text-align: right;
     font-size: 0.9em;

==============================================================================
Revision: 8447b3e58bce
Author:   Janne Härkönen <[email protected]>
Date:     Wed Jun 15 03:41:12 2011
Log:      serializing: write settings as separate JSON object
http://code.google.com/p/robotframework/source/detail?r=8447b3e58bce

Added:
 /src/robot/serializing/json.py
Modified:
 /src/robot/__init__.py
 /src/robot/serializing/jsondatamodel.py
 /src/robot/serializing/serialize_log.py
 /src/robot/serializing/testoutput.py
 /utest/serializing/test_js_serializer.py
 /utest/serializing/test_reporting.py

=======================================
--- /dev/null
+++ /src/robot/serializing/json.py      Wed Jun 15 03:41:12 2011
@@ -0,0 +1,59 @@
+#  Copyright 2008-2011 Nokia Siemens Networks Oyj
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+def encode_basestring(string):
+    def get_matching_char(c):
+        val = ord(c)
+        if val < 127 and val > 31:
+            return c
+        return '\\u' + hex(val)[2:].rjust(4,'0')
+    string = string.replace('\\', '\\\\')
+    string = string.replace('"', '\\"')
+    string = string.replace('\b', '\\b')
+    string = string.replace('\f', '\\f')
+    string = string.replace('\n', '\\n')
+    string = string.replace('\r', '\\r')
+    string = string.replace('\t', '\\t')
+    result = []
+    for c in string:
+        result += [get_matching_char(c)]
+    return '"'+''.join(result)+'"'
+
+def json_dump(data, output):
+    if data is None:
+        output.write('null')
+    elif isinstance(data, int):
+        output.write(str(data))
+    elif isinstance(data, 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)
+            if index < len(data)-1:
+                output.write(',')
+        output.write(']')
+    elif type(data) == dict:
+        output.write('{')
+        for index, item in enumerate(data.items()):
+            json_dump(item[0], output)
+            output.write(':')
+            json_dump(item[1], output)
+            if index < len(data)-1:
+                output.write(',')
+        output.write('}')
+    else:
+ raise Exception('Data type (%s) serialization not supported' % type(data))
=======================================
--- /src/robot/__init__.py      Mon Jun 13 04:24:20 2011
+++ /src/robot/__init__.py      Wed Jun 15 03:41:12 2011
@@ -132,7 +132,7 @@
         _, settings = settings.get_rebot_datasources_and_settings()
         if settings['SplitOutputs'] > 0:
             raise Exception('Splitting? No way!')
-        Reporter().execute(settings, output_src)
+        Reporter(settings).execute(output_src)
     LOGGER.close()
     return suite

@@ -155,7 +155,7 @@
     settings = RebotSettings(options)
     LOGGER.register_console_logger(colors=settings['MonitorColors'])
     LOGGER.disable_message_cache()
-    suite = Reporter().execute_rebot(settings, *datasources)
+    suite = Reporter(settings).execute_rebot(*datasources)
     LOGGER.close()
     return suite

=======================================
--- /src/robot/serializing/jsondatamodel.py     Wed Jun 15 01:08:49 2011
+++ /src/robot/serializing/jsondatamodel.py     Wed Jun 15 03:41:12 2011
@@ -15,19 +15,29 @@
 from robot import utils

 from elementhandlers import TextIndex
+import json

 class DataModel(object):

     def __init__(self, robot_data):
         self._robot_data = robot_data
+        self._settings = None

     def set_generated(self, timetuple):
self._robot_data['generatedMillis'] = long(time.mktime(timetuple))*1000-self._robot_data['baseMillis'] self._robot_data['generatedTimestamp'] = utils.format_time(timetuple, daytimesep='&nbsp;', gmtsep='&nbsp;')

+    def set_settings(self, settings):
+        self._settings = settings
+
     def write_to(self, output):
-        output.write('window.output = ')
-        json_dump(self._robot_data, output)
+        self._dump_json('window.output = ', self._robot_data, output)
+        if self._settings:
+            self._dump_json('window.settings = ', self._settings, output)
+
+    def _dump_json(self, name, data, output):
+        output.write(name)
+        json.json_dump(data, output)
         output.write(';\n')

     def remove_keywords(self):
@@ -59,48 +69,4 @@
                 self._collect_used_text_indices(item.values(), result)
         return result

-def encode_basestring(string):
-    def get_matching_char(c):
-        val = ord(c)
-        if val < 127 and val > 31:
-            return c
-        return '\\u' + hex(val)[2:].rjust(4,'0')
-    string = string.replace('\\', '\\\\')
-    string = string.replace('"', '\\"')
-    string = string.replace('\b', '\\b')
-    string = string.replace('\f', '\\f')
-    string = string.replace('\n', '\\n')
-    string = string.replace('\r', '\\r')
-    string = string.replace('\t', '\\t')
-    result = []
-    for c in string:
-        result += [get_matching_char(c)]
-    return '"'+''.join(result)+'"'
-
-def json_dump(data, output):
-    if data is None:
-        output.write('null')
-    elif isinstance(data, int):
-        output.write(str(data))
-    elif isinstance(data, 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)
-            if index < len(data)-1:
-                output.write(',')
-        output.write(']')
-    elif type(data) == dict:
-        output.write('{')
-        for index, item in enumerate(data.items()):
-            json_dump(item[0], output)
-            output.write(':')
-            json_dump(item[1], output)
-            if index < len(data)-1:
-                output.write(',')
-        output.write('}')
-    else:
- raise Exception('Data type (%s) serialization not supported' % type(data))
+
=======================================
--- /src/robot/serializing/serialize_log.py     Wed Jun 15 01:09:45 2011
+++ /src/robot/serializing/serialize_log.py     Wed Jun 15 03:41:12 2011
@@ -28,25 +28,24 @@
 CSS_MEDIA_TYPE_REGEXP = re.compile('media=\"([^\"]+)\"')


-def serialize_log(output, log_path, title=None):
+def serialize_log(output, log_path):
     if log_path is None:
         return
-    _build_file(log_path, output, title, LOG_TEMPLATE)
-
-def serialize_report(output, report_path, title=None, log_path=None):
+    _build_file(log_path, output, LOG_TEMPLATE)
+
+def serialize_report(output, report_path):
     if report_path is None:
         return
-    _build_file(report_path, output, title, REPORT_TEMPLATE,
-                _relative_log_path(report_path, log_path))
+    _build_file(report_path, output, REPORT_TEMPLATE)

 def _relative_log_path(report, log):
     if not log:
         return None
     return utils.get_link_path(log, os.path.dirname(report))

-def _build_file(outpath, output, title, template, log_path=None):
+def _build_file(outpath, output, template):
     with codecs.open(outpath, 'w', encoding='UTF-8') as outfile:
-        builder = OutputFileBuilder(outfile, output, title, log_path)
+        builder = OutputFileBuilder(outfile, output)
         with open(template, 'r') as tmpl:
             for line in tmpl:
                 builder.line(line)
@@ -54,18 +53,12 @@

 class OutputFileBuilder(object):

-    def __init__(self, outfile, output, title, log_path=None):
+    def __init__(self, outfile, output):
         self._outfile = outfile
-        self._log_path = log_path
         self._output = output
-        self._title = title

     def line(self, line):
-        if self._is_title_line_to_handle(line):
-            self._write_title()
-        elif self._is_log_path_line_to_handle(line):
-            self._replace_log_path(line)
-        elif self._is_output_js(line):
+        if self._is_output_js(line):
             self._write_output_js()
         elif self._is_css_line(line):
             self._write_lines_css(line)
@@ -74,18 +67,6 @@
         else:
             self._outfile.write(line)

-    def _is_title_line_to_handle(self, line):
-        return self._title is not None and line.startswith('<title>')
-
-    def _write_title(self):
-        self._outfile.write('<title>%s</title>\n' % self._title)
-
-    def _is_log_path_line_to_handle(self, line):
-        return self._log_path and 'log.html' in line
-
-    def _replace_log_path(self, line):
-        self._outfile.write(line.replace('log.html', self._log_path))
-
     def _is_output_js(self, line):
         return line.startswith('<!-- OUTPUT JS -->')

=======================================
--- /src/robot/serializing/testoutput.py        Wed Jun 15 01:12:19 2011
+++ /src/robot/serializing/testoutput.py        Wed Jun 15 03:41:12 2011
@@ -36,61 +36,98 @@

 class Reporter(object):

-    def __init__(self):
+    def __init__(self, settings):
         self._robot_test_output_cached = None
         self._temp_file = None
         self._suite = None
-
-    def _make_report(self, report_path, log_path, data_model, settings):
+        self._settings = settings
+
+    def _make_report(self, report_path, data_model):
         if report_path:
- serialize_report(data_model, report_path, settings['ReportTitle'], log_path)
+            data_model.set_settings(self._get_report_settings())
+            serialize_report(data_model, report_path)
             LOGGER.output_file('Report', report_path)

-    def _make_log(self, log_path, data_model, settings):
+    def _get_report_settings(self):
+        return {
+            'title': self._settings['ReportTitle'],
+            'background' : self._resolve_background_colors(),
+            'logURL': self._url_from_path(self._parse_file('Report'),
+                                          self._parse_file('Log'))
+        }
+
+    def _url_from_path(self, source, dest):
+        if not dest:
+            return None
+        return utils.get_link_path(dest, os.path.dirname(source))
+
+    def _resolve_background_colors(self):
+        color_str = self._settings['ReportBackground']
+        if color_str and color_str.count(':') not in [1, 2]:
+            color_str = None
+        if not color_str:
+            color_str = '#99FF66:#FF3333'
+        colors = color_str.split(':', 2)
+        if len(colors) == 2:
+            colors.insert(1, colors[0])
+ return {'pass': colors[0], 'nonCriticalFail': colors[1], 'fail': colors[2]}
+
+    def _make_log(self, log_path, data_model):
         if log_path:
-            serialize_log(data_model, log_path, settings['LogTitle'])
+            data_model.set_settings(self._get_log_settings())
+            serialize_log(data_model, log_path)
             LOGGER.output_file('Log', log_path)

-    def _make_xunit(self, xunit_path, data_source, settings):
+
+    def _get_log_settings(self):
+        return {
+            'title': self._settings['ReportTitle'],
+            'reportURL': self._url_from_path(self._parse_file('Log'),
+                                             self._parse_file('Report'))
+        }
+
+    def _make_xunit(self, xunit_path, data_source):
         if xunit_path:
- self._robot_test_output([data_source], settings).serialize_xunit(xunit_path)
-
-    def _robot_test_output(self, data_sources, settings):
+ self._robot_test_output([data_source]).serialize_xunit(xunit_path)
+
+    def _robot_test_output(self, data_sources):
         if self._robot_test_output_cached is None:
- self._suite, exec_errors = process_outputs(data_sources, settings)
-            self._suite.set_options(settings)
- self._robot_test_output_cached = RobotTestOutput(self._suite, exec_errors, settings) + self._suite, exec_errors = process_outputs(data_sources, self._settings)
+            self._suite.set_options(self._settings)
+ self._robot_test_output_cached = RobotTestOutput(self._suite, exec_errors, self._settings)
         return self._robot_test_output_cached

-    def _combine_outputs(self, data_sources, settings):
-        output_file = self._parse_file(settings['Output'])
+    def _combine_outputs(self, data_sources):
+        output_file = self._parse_file('Output')
         if output_file is None:
handle, output_file = tempfile.mkstemp(suffix='.xml', prefix='rebot-')
             os.close(handle)
             self._temp_file = output_file
- self._robot_test_output(data_sources, settings).serialize_output(output_file, log=not self._temp_file) + self._robot_test_output(data_sources).serialize_output(output_file, log=not self._temp_file)
         return output_file

-    def execute_rebot(self, settings, *data_sources):
-        combined = self._combine_outputs(data_sources, settings)
-        self.execute(settings, combined)
+    def execute_rebot(self, *data_sources):
+        combined = self._combine_outputs(data_sources)
+        self.execute(combined)
         if self._temp_file:
             os.remove(self._temp_file)
         return self._suite

-    def execute(self, settings, data_source):
+    def execute(self, data_source):
         data_model = jsparser.create_datamodel_from(data_source)
         data_model.set_generated(time.localtime())
-        log_path = self._parse_file(settings['Log'])
-        report_path = self._parse_file(settings['Report'])
-        self._make_log(log_path, data_model, settings)
+        log_path = self._parse_file('Log')
+        report_path = self._parse_file('Report')
+        self._make_log(log_path, data_model)
         data_model.remove_keywords()
-        self._make_report(report_path, log_path, data_model, settings)
-        xunit_path = self._parse_file(settings['XUnitFile'])
-        self._make_xunit(xunit_path, data_source, settings)
-
-    def _parse_file(self, string):
-        return string if string != 'NONE' else None
+        self._make_report(report_path, data_model)
+        xunit_path = self._parse_file('XUnitFile')
+        self._make_xunit(xunit_path, data_source)
+
+    def _parse_file(self, name):
+        value = self._settings[name]
+        return value if value != 'NONE' else None
+


 # TODO: Most (all?) of this class is dead code
=======================================
--- /utest/serializing/test_js_serializer.py    Wed Jun 15 01:08:49 2011
+++ /utest/serializing/test_js_serializer.py    Wed Jun 15 03:41:12 2011
@@ -13,7 +13,7 @@
 import xml.sax as sax

 from robot.serializing.jsparser import _RobotOutputHandler
-from robot.serializing.jsondatamodel import json_dump
+from robot.serializing.json import json_dump
 from robot.serializing.elementhandlers import Context
 from robot.utils.asserts import assert_equals, assert_true

=======================================
--- /utest/serializing/test_reporting.py        Wed Jun 15 02:33:16 2011
+++ /utest/serializing/test_reporting.py        Wed Jun 15 03:41:12 2011
@@ -39,7 +39,6 @@
 class TestReporting(unittest.TestCase):

     def setUp(self):
-        self._reporter = Reporter()
         self._settings = {
             'Report': 'NONE',
             'Log': 'NONE',
@@ -70,12 +69,12 @@
             'EndTime': 0,
             'LogLevel': 'INFO'
         }
+        self._reporter = Reporter(self._settings)
         self._original_logger = robot.serializing.testoutput.LOGGER
         robot.serializing.testoutput.LOGGER = Logger()
robot.serializing.testoutput.LOGGER.disable_automatic_console_logger()
         self._log_results = set_serialize_log_mock()
         self._report_results = set_serialize_report_mock()
-        #self._process_outputs_results = set_process_outputs_mock()

     def tearDown(self):
         robot.serializing.testoutput.LOGGER = self._original_logger
@@ -83,33 +82,31 @@
     def test_generate_report_and_log(self):
         self._settings['Log'] = 'log.html'
         self._settings['Report'] = 'report.html'
-        self._reporter.execute(self._settings, resources.GOLDEN_OUTPUT)
+        self._reporter.execute(resources.GOLDEN_OUTPUT)
         self._assert_expected_log('log.html')
         self._assert_expected_report('report.html')
-        self._assert_log_link_in_report('log.html')

     def test_no_generation(self):
-        self._reporter.execute(self._settings, resources.GOLDEN_OUTPUT)
+        self._reporter.execute(resources.GOLDEN_OUTPUT)
         self._assert_no_log()
         self._assert_no_report()

     def test_only_log(self):
         self._settings['Log'] = 'only-log.html'
-        self._reporter.execute(self._settings, resources.GOLDEN_OUTPUT)
+        self._reporter.execute(resources.GOLDEN_OUTPUT)
         self._assert_expected_log('only-log.html')
         self._assert_no_report()

     def test_only_report(self):
         self._settings['Report'] = 'reports-only.html'
-        self._reporter.execute(self._settings, resources.GOLDEN_OUTPUT)
+        self._reporter.execute(resources.GOLDEN_OUTPUT)
         self._assert_no_log()
         self._assert_expected_report('reports-only.html')
-        self._assert_no_log_links_in_report()

     def test_multiple_outputs(self):
         self._settings['Log'] = 'log.html'
         self._settings['Report'] = 'report.html'
- self._reporter.execute_rebot(self._settings, *[resources.GOLDEN_OUTPUT, resources.GOLDEN_OUTPUT2]) + self._reporter.execute_rebot(*[resources.GOLDEN_OUTPUT, resources.GOLDEN_OUTPUT2])
         self._assert_expected_log('log.html')
         self._assert_expected_report('report.html')

@@ -119,12 +116,6 @@
     def _assert_expected_report(self, expected_file_name):
self.assertEquals(self._report_results['report_path'], expected_file_name)

-    def _assert_log_link_in_report(self, expected_log_link):
- self.assertEquals(self._report_results['logpath'], expected_log_link)
-
-    def _assert_no_log_links_in_report(self):
-        self._assert_log_link_in_report(None)
-
     def _assert_no_log(self):
         self._assert_expected_log(None)


==============================================================================
Revision: 65019c59d464
Author:   Janne Härkönen <[email protected]>
Date:     Wed Jun 15 03:41:24 2011
Log:      merge
http://code.google.com/p/robotframework/source/detail?r=65019c59d464


Reply via email to