5 new revisions:
Revision: 3db96590a149
Author: Pekka Klärck
Date: Sun Jan 29 02:06:52 2012
Log: Monitor: Testability. This also helps adding support for
overriding st...
http://code.google.com/p/robotframework/source/detail?r=3db96590a149
Revision: d2b31d8f7151
Author: Pekka Klärck
Date: Sun Jan 29 02:08:21 2012
Log: fixed test when global variables have been set (global state FTL)
http://code.google.com/p/robotframework/source/detail?r=d2b31d8f7151
Revision: 20b1dc4f57c2
Author: Pekka Klärck
Date: Sun Jan 29 02:48:12 2012
Log: fixed creating log/report when output has no times and thus no
basemil...
http://code.google.com/p/robotframework/source/detail?r=20b1dc4f57c2
Revision: 577347243d94
Author: Pekka Klärck
Date: Sun Jan 29 04:08:47 2012
Log: robot.run and robot.run_rebot: Fixed output when executing
multiple ti...
http://code.google.com/p/robotframework/source/detail?r=577347243d94
Revision: 6b94e37bfc4c
Author: Pekka Klärck
Date: Sun Jan 29 04:08:56 2012
Log: Automated merge with https://code.google.com/p/robotframework/
http://code.google.com/p/robotframework/source/detail?r=6b94e37bfc4c
==============================================================================
Revision: 3db96590a149
Author: Pekka Klärck
Date: Sun Jan 29 02:06:52 2012
Log: Monitor: Testability. This also helps adding support for
overriding stdout and stderr.
http://code.google.com/p/robotframework/source/detail?r=3db96590a149
Modified:
/src/robot/output/monitor.py
=======================================
--- /src/robot/output/monitor.py Tue Aug 16 13:45:06 2011
+++ /src/robot/output/monitor.py Sun Jan 29 02:06:52 2012
@@ -21,9 +21,11 @@
class CommandLineMonitor:
- def __init__(self, width=78, colors='AUTO'):
+ def __init__(self, width=78, colors='AUTO', stdout=None, stderr=None):
self._width = width
- self._highlighter = StatusHighlighter(colors)
+ self._stdout = stdout or sys.__stdout__
+ self._stderr = stderr or sys.__stderr__
+ self._highlighter = StatusHighlighter(colors, self._stdout,
self._stderr)
self._is_logged = IsLogged('WARN')
self._started = False
@@ -51,7 +53,7 @@
def message(self, msg):
if self._is_logged(msg.level):
self._write_with_highlighting('[ ', msg.level, ' ] ' +
msg.message,
- stream=sys.__stderr__)
+ error=True)
def output_file(self, name, path):
self._write('%-8s %s' % (name+':', path))
@@ -78,31 +80,32 @@
def _write_separator(self, sep_char):
self._write(sep_char * self._width)
- def _write(self, message, newline=True, stream=sys.__stdout__):
+ def _write(self, message, newline=True, error=False):
+ stream = self._stdout if not error else self._stderr
if newline:
message += '\n'
stream.write(utils.encode_output(message).replace('\t', ' '*8))
stream.flush()
def _write_with_highlighting(self, before, highlighted, after,
- newline=True, stream=sys.__stdout__):
- self._write(before, newline=False, stream=stream)
+ newline=True, error=False):
+ stream = self._stdout if not error else self._stderr
+ self._write(before, newline=False, error=error)
self._highlighter.start(highlighted, stream)
- self._write(highlighted, newline=False, stream=stream)
+ self._write(highlighted, newline=False, error=error)
self._highlighter.end()
- self._write(after, newline=newline, stream=stream)
+ self._write(after, newline=newline, error=error)
class StatusHighlighter:
- def __init__(self, colors):
+ def __init__(self, colors, *streams):
self._current = None
- self._highlighters = {
- sys.__stdout__: self._get_highlighter(sys.__stdout__, colors),
- sys.__stderr__: self._get_highlighter(sys.__stderr__, colors)
- }
-
- def start(self, message, stream=sys.__stdout__):
+ self._colors = colors.upper()
+ self._highlighters = dict((stream, self._get_highlighter(stream))
+ for stream in streams)
+
+ def start(self, message, stream):
self._current = self._highlighters[stream]
{'PASS': self._current.green,
'FAIL': self._current.red,
@@ -112,10 +115,10 @@
def end(self):
self._current.reset()
- def _get_highlighter(self, stream, colors):
+ def _get_highlighter(self, stream):
auto = hasattr(stream, 'isatty') and stream.isatty()
enable = {'AUTO': auto,
'ON': True,
'FORCE': True, # compatibility with 2.5.5 and earlier
- 'OFF': False}.get(colors.upper(), auto)
+ 'OFF': False}.get(self._colors, auto)
return Highlighter(stream) if enable else NoHighlighting(stream)
==============================================================================
Revision: d2b31d8f7151
Author: Pekka Klärck
Date: Sun Jan 29 02:08:21 2012
Log: fixed test when global variables have been set (global state FTL)
http://code.google.com/p/robotframework/source/detail?r=d2b31d8f7151
Modified:
/utest/running/test_namespace.py
=======================================
--- /utest/running/test_namespace.py Mon Jan 2 15:01:11 2012
+++ /utest/running/test_namespace.py Sun Jan 29 02:08:21 2012
@@ -3,10 +3,11 @@
import pkgutil
from robot.running import namespace
-from robot.running.namespace import _VariableScopes
+from robot.running.namespace import _VariableScopes, GLOBAL_VARIABLES
from robot import libraries
from robot.utils.asserts import assert_equals
+
class TestNamespace(unittest.TestCase):
def test_standard_library_names(self):
@@ -15,11 +16,12 @@
if name[0].isupper() and not
name.startswith('Deprecated'))
assert_equals(set(exp_libs), namespace.STDLIB_NAMES)
+
class TestVariableScopes(unittest.TestCase):
def test_len(self):
assert_equals(len(_VariableScopes(None, None)), 0)
- assert_equals(len(_VariableScopes(DummySuite(), None)), 2)
+ assert_equals(len(_VariableScopes(DummySuite(), None)), 2 +
len(GLOBAL_VARIABLES))
assert_equals(len(_VariableScopes(None,
_VariableScopes(DummySuite(), None))), 0)
==============================================================================
Revision: 20b1dc4f57c2
Author: Pekka Klärck
Date: Sun Jan 29 02:48:12 2012
Log: fixed creating log/report when output has no times and thus no
basemillis
http://code.google.com/p/robotframework/source/detail?r=20b1dc4f57c2
Modified:
/atest/robot/output/processing_output.txt
/src/robot/reporting/jsexecutionresult.py
=======================================
--- /atest/robot/output/processing_output.txt Thu Dec 1 05:37:45 2011
+++ /atest/robot/output/processing_output.txt Sun Jan 29 02:48:12 2012
@@ -28,7 +28,8 @@
Minimal hand-created output
[Documentation] Testing minimal hand created suite with tests or
subsuites
- Run Rebot ${EMPTY} rebot/created_normal.xml
+ Run Rebot --log log_from_created_output.html rebot/created_normal.xml
+ File Should Not Be Empty ${OUTDIR}/log_from_created_output.html
Check Names ${SUITE} Root
Should Contain Suites ${SUITE} Sub 1 Sub 2
Check Names ${SUITE.suites[0]} Sub 1 Root.
=======================================
--- /src/robot/reporting/jsexecutionresult.py Wed Dec 7 23:39:37 2011
+++ /src/robot/reporting/jsexecutionresult.py Sun Jan 29 02:48:12 2012
@@ -21,11 +21,11 @@
class JsExecutionResult(object):
- def __init__(self, suite, statistics, errors, strings, basemillis,
+ def __init__(self, suite, statistics, errors, strings, basemillis=None,
split_results=None):
self.suite = suite
self.strings = strings
- self.data = self._get_data(statistics, errors, basemillis)
+ self.data = self._get_data(statistics, errors, basemillis or 0)
self.split_results = split_results or []
def _get_data(self, statistics, errors, basemillis):
==============================================================================
Revision: 577347243d94
Author: Pekka Klärck
Date: Sun Jan 29 04:08:47 2012
Log: robot.run and robot.run_rebot: Fixed output when executing
multiple times. Always return an rc and never raise an exception.
Update issue 1045
Status: Done
The actual change is done but code is somewhat ugly. Cleaning up is left
for issue 480.
http://code.google.com/p/robotframework/source/detail?r=577347243d94
Added:
/utest/api/test_run_and_rebot.py
Modified:
/src/robot/__init__.py
=======================================
--- /dev/null
+++ /utest/api/test_run_and_rebot.py Sun Jan 29 04:08:47 2012
@@ -0,0 +1,104 @@
+import unittest
+import sys
+import tempfile
+from os.path import abspath, dirname, join, exists
+from os import remove
+from StringIO import StringIO
+
+from robot.utils.asserts import assert_equals
+from robot import run, run_rebot
+
+ROOT = dirname(dirname(dirname(abspath(__file__))))
+TEMP = tempfile.gettempdir()
+LOG = 'Log: %s' % join(TEMP, 'log.html')
+
+
+class Base(unittest.TestCase):
+
+ def setUp(self):
+ self.orig__stdout__ = sys.__stdout__
+ self.orig__stderr__ = sys.__stderr__
+ self.orig_stdout = sys.stdout
+ self.orig_stderr = sys.stderr
+ sys.__stdout__ = StringIO()
+ sys.__stderr__ = StringIO()
+ sys.stdout = StringIO()
+ sys.stderr = StringIO()
+ if exists(LOG):
+ remove(LOG)
+
+ def tearDown(self):
+ sys.__stdout__ = self.orig__stdout__
+ sys.__stderr__ = self.orig__stderr__
+ sys.stdout = self.orig_stdout
+ sys.stderr = self.orig_stderr
+
+ def _assert_outputs(self, stdout=None, stderr=None):
+ self._assert_output(sys.__stdout__, stdout)
+ self._assert_output(sys.__stderr__, stderr)
+ self._assert_output(sys.stdout, None)
+ self._assert_output(sys.stderr, None)
+
+ def _assert_output(self, stream, expected):
+ output = stream.getvalue()
+ if expected:
+ self._assert_output_contains(output, expected)
+ else:
+ self._assert_no_output(output)
+
+ def _assert_no_output(self, output):
+ if output:
+ raise AssertionError('Expected output to be empty:\n%s' %
output)
+
+ def _assert_output_contains(self, output, expected_items):
+ for expected in expected_items:
+ content, count = expected
+ if output.count(content) != count:
+ raise AssertionError("'%s' not %d times in output:\n%s"
+ % (content, count, output))
+
+
+class TestRun(Base):
+ data = join(ROOT, 'atest', 'testdata', 'misc', 'pass_and_fail.html')
+ nonex = join(TEMP, 'non-existing-file-this-is.txt')
+
+ def test_run_once(self):
+ assert_equals(run(self.data, outputdir=TEMP, report='none'), 1)
+ self._assert_outputs([('Pass And Fail', 2), (LOG, 1), ('Report:',
0)])
+ assert exists(LOG)
+
+ def test_run_multiple_times(self):
+ assert_equals(run(self.data, output='NONE', critical='nomatch'), 0)
+ assert_equals(run(self.data, output='NONE', name='New Name'), 1)
+ self._assert_outputs([('Pass And Fail', 2), ('New Name', 2), (LOG,
0)])
+
+ def test_run_fails(self):
+ assert_equals(run(self.nonex), 252)
+ assert_equals(run(self.data, outputdir=TEMP), 1)
+ self._assert_outputs(stdout=[('Pass And Fail', 2), (LOG, 1)],
+ stderr=[('[ ERROR ]', 1), (self.nonex, 1),
('--help', 1)])
+
+
+class TestRebot(Base):
+ data = join(ROOT, 'atest', 'testdata', 'rebot', 'created_normal.xml')
+ nonex = join(TEMP, 'non-existing-file-this-is.xml')
+
+ def test_run_once(self):
+ assert_equals(run_rebot(self.data, outputdir=TEMP, report='NONE'),
1)
+ self._assert_outputs([(LOG, 1, ('Report:', 0))])
+ assert exists(LOG)
+
+ def test_run_multiple_times(self):
+ assert_equals(run_rebot(self.data, outputdir=TEMP,
critical='nomatch'), 0)
+ assert_equals(run_rebot(self.data, outputdir=TEMP, name='New
Name'), 1)
+ self._assert_outputs([(LOG, 2)])
+
+ def test_run_fails(self):
+ assert_equals(run_rebot(self.nonex), 252)
+ assert_equals(run_rebot(self.data, outputdir=TEMP), 1)
+ self._assert_outputs(stdout=[(LOG, 1)],
+ stderr=[('[ ERROR ]', 1), (self.nonex, 2),
('--help', 1)])
+
+
+if __name__ == '__main__':
+ unittest.main()
=======================================
--- /src/robot/__init__.py Fri Jan 13 02:57:20 2012
+++ /src/robot/__init__.py Sun Jan 29 04:08:47 2012
@@ -56,7 +56,7 @@
_report_error(unicode(err), help=True)
return DATA_ERROR
LOGGER.info('Data sources: %s' % utils.seq2str(datasources))
- return _execute(method, datasources, options)
+ return method(*datasources, **options)
def _parse_arguments(cliargs, usage, **argparser_config):
ap = utils.ArgumentParser(usage, get_full_version())
@@ -66,7 +66,7 @@
def _execute(method, datasources, options):
try:
- rc = method(*datasources, **options)
+ rc = method(datasources, options)
except DataError, err:
_report_error(unicode(err), help=True)
return DATA_ERROR
@@ -90,6 +90,8 @@
pybot/jybot from command line. Options are given as keywords arguments
and
their names are same as long command line options without hyphens.
+ Returns a return code similarly as when running on the command line.
+
Examples:
run('/path/to/tests.html')
run('/path/to/tests.html', '/path/to/tests2.html', log='mylog.html')
@@ -98,6 +100,9 @@
pybot /path/to/tests.html
pybot --log mylog.html /path/to/tests.html /path/to/tests2.html
"""
+ return _execute(_run, datasources, options)
+
+def _run(datasources, options):
STOP_SIGNAL_MONITOR.start()
settings = RobotSettings(options)
pyloggingconf.initialize(settings['LogLevel'])
@@ -123,6 +128,8 @@
rebot from command line. Options are given as keywords arguments and
their names are same as long command line options without hyphens.
+ Returns a return code similarly as when running on the command line.
+
Examples:
run_rebot('/path/to/output.xml')
run_rebot('/path/out1.xml', '/path/out2.xml', report='myrep.html',
log='NONE')
@@ -131,6 +138,9 @@
rebot /path/to/output.xml
rebot --report myrep.html --log NONE /path/out1.xml /path/out2.xml
"""
+ return _execute(_rebot, datasources, options)
+
+def _rebot(datasources, options):
settings = RebotSettings(options)
LOGGER.register_console_logger(colors=settings['MonitorColors'])
LOGGER.disable_message_cache()
==============================================================================
Revision: 6b94e37bfc4c
Author: Pekka Klärck
Date: Sun Jan 29 04:08:56 2012
Log: Automated merge with https://code.google.com/p/robotframework/
http://code.google.com/p/robotframework/source/detail?r=6b94e37bfc4c