Revision: 3236
Author: KariHusa
Date: Fri May 7 05:25:59 2010
Log: Refactoring
http://code.google.com/p/robotframework/source/detail?r=3236
Modified:
/trunk/src/robot/common/handlers.py
/trunk/src/robot/libraries/BuiltIn.py
/trunk/src/robot/output/output.py
/trunk/src/robot/running/fixture.py
/trunk/src/robot/running/handlers.py
/trunk/src/robot/running/keywords.py
/trunk/src/robot/running/model.py
/trunk/src/robot/running/namespace.py
/trunk/src/robot/running/userkeyword.py
/trunk/utest/running/test_keywords.py
/trunk/utest/running/test_testlibrary.py
=======================================
--- /trunk/src/robot/common/handlers.py Thu Apr 15 00:44:41 2010
+++ /trunk/src/robot/common/handlers.py Fri May 7 05:25:59 2010
@@ -30,5 +30,8 @@
self._error = error
self.timeout = ''
+ def init_keyword(self, varz):
+ pass
+
def run(self, *args):
raise DataError(self._error)
=======================================
--- /trunk/src/robot/libraries/BuiltIn.py Thu May 6 02:04:00 2010
+++ /trunk/src/robot/libraries/BuiltIn.py Fri May 7 05:25:59 2010
@@ -759,7 +759,8 @@
if not utils.is_str(name):
raise DataError('Keyword name must be a string')
kw = Keyword(name, args)
- return kw.run(output.OUTPUT, NAMESPACES.current)
+ from robot.running.model import ExecutionContext
+ return kw.run(ExecutionContext(NAMESPACES.current, output.OUTPUT))
def run_keyword_if(self, condition, name, *args):
"""Runs the given keyword with the given arguments, if `condition`
is true.
=======================================
--- /trunk/src/robot/output/output.py Tue Mar 23 04:15:41 2010
+++ /trunk/src/robot/output/output.py Fri May 7 05:25:59 2010
@@ -61,18 +61,16 @@
def start_suite(self, suite):
LOGGER.start_suite(suite)
if self._xmllogger.started_output:
- suite.namespace.variables.set_global('${OUTPUT_FILE}',
-
self._xmllogger.started_output)
+
suite.context.output_file_changed(self._xmllogger.started_output)
if self._namegen:
- suite.namespace.variables.set_global('${LOG_FILE}',
-
self._namegen.get_name())
+ suite.context.log_file_changed(self._namegen.get_name())
def end_suite(self, suite):
LOGGER.end_suite(suite)
if self._xmllogger.ended_output:
LOGGER.output_file('Output', self._xmllogger.ended_output)
orig_outpath = self._settings['Output']
- suite.namespace.variables.set_global('${OUTPUT_FILE}',
orig_outpath)
+ suite.context.output_file_changed(orig_outpath)
self._create_split_log(self._xmllogger.ended_output, suite)
def _create_split_log(self, outpath, suite):
@@ -81,7 +79,7 @@
logpath = self._namegen.get_prev()
output = robot.serializing.SplitSubTestOutput(outpath)
output.serialize_log(logpath)
- suite.namespace.variables.set_global('${LOG_FILE}',
self._namegen.get_base())
+ suite.context.log_file_changed(self._namegen.get_base())
def start_test(self, test):
LOGGER.start_test(test)
=======================================
--- /trunk/src/robot/running/fixture.py Wed May 5 00:15:11 2010
+++ /trunk/src/robot/running/fixture.py Fri May 7 05:25:59 2010
@@ -30,10 +30,10 @@
return None
return Keyword(kwdata[0], kwdata[1:],
type=self.__class__.__name__.lower())
- def run(self, output, namespace, error_listener):
+ def run(self, context, error_listener):
if self._keyword:
try:
- self._keyword.run(output, namespace)
+ self._keyword.run(context)
except ExecutionFailed, err:
error_listener.notify(err)
=======================================
--- /trunk/src/robot/running/handlers.py Thu May 6 00:18:28 2010
+++ /trunk/src/robot/running/handlers.py Fri May 7 05:25:59 2010
@@ -85,11 +85,15 @@
return self._get_global_handler(method, name)
return None
- def run(self, output, namespace, args):
- positional, named = self.arguments.resolve(args,
namespace.variables,
+ def init_keyword(self, varz):
+ pass
+
+ def run(self, context, args):
+ output = context.output
+ positional, named = self.arguments.resolve(args,
context.get_current_vars(),
output)
runner = self._runner_for(self._current_handler(), output,
positional,
- named, self._get_timeout(namespace))
+ named,
self._get_timeout(context.namespace))
return self._run_with_output_captured_and_signal_monitor(runner,
output)
def _runner_for(self, handler, output, positional, named, timeout):
=======================================
--- /trunk/src/robot/running/keywords.py Thu May 6 00:51:55 2010
+++ /trunk/src/robot/running/keywords.py Fri May 7 05:25:59 2010
@@ -24,11 +24,11 @@
def __init__(self, kwdata):
self._keywords = [ _KeywordFactory(kw) for kw in kwdata ]
- def run(self, output, namespace):
+ def run(self, context):
errors = []
for kw in self._keywords:
try:
- kw.run(output, namespace)
+ kw.run(context)
except ExecutionFailed, err:
errors.extend(err.get_errors())
if not err.cont:
@@ -60,28 +60,27 @@
BaseKeyword.__init__(self, name, args, type=type)
self.handler_name = name
- def run(self, output, namespace):
- handler = namespace.get_handler(self.handler_name)
- if handler.type == 'user':
- handler.init_user_keyword(namespace.variables)
- self.name = self._get_name(handler.longname, namespace.variables)
+ def run(self, context):
+ handler = context.get_handler(self.handler_name)
+ handler.init_keyword(context.get_current_vars())
+ self.name = self._get_name(handler.longname,
context.get_current_vars())
self.doc = handler.shortdoc
self.starttime = utils.get_timestamp()
- output.start_keyword(self)
+ context.start_keyword(self)
if self.doc.startswith('*DEPRECATED*'):
msg = self.doc.replace('*DEPRECATED*', '', 1).strip()
name = self.name.split('} = ', 1)[-1] # Remove possible
variable
- output.warn("Keyword '%s' is deprecated. %s" % (name, msg))
+ context.warn("Keyword '%s' is deprecated. %s" % (name, msg))
try:
- ret = self._run(handler, output, namespace)
- output.trace('Return: %s' % utils.safe_repr(ret))
+ ret = self._run(handler, context)
+ context.trace('Return: %s' % utils.safe_repr(ret))
except ExecutionFailed, err:
self.status = 'FAIL'
else:
self.status = 'PASS'
self.endtime = utils.get_timestamp()
self.elapsedtime = utils.get_elapsed_time(self.starttime,
self.endtime)
- output.end_keyword(self)
+ context.end_keyword(self)
if self.status == 'FAIL':
raise err
return ret
@@ -89,21 +88,21 @@
def _get_name(self, handler_name, variables):
return handler_name
- def _run(self, handler, output, namespace):
+ def _run(self, handler, context):
try:
- return handler.run(output, namespace, self.args[:])
+ return handler.run(context, self.args[:])
except ExecutionFailed:
raise
except:
- self._report_failure(output, namespace)
-
- def _report_failure(self, output, namespace):
+ self._report_failure(context)
+
+ def _report_failure(self, context):
error_details = utils.ErrorDetails()
- output.fail(error_details.message)
+ context.output.fail(error_details.message)
if error_details.traceback:
- output.debug(error_details.traceback)
+ context.output.debug(error_details.traceback)
raise HandlerExecutionFailed(error_details,
-
self._in_test_or_suite_teardown(namespace))
+
self._in_test_or_suite_teardown(context.namespace))
def _in_test_or_suite_teardown(self, namespace):
test_or_suite = namespace.test or namespace.suite
@@ -123,32 +122,32 @@
varz.append(self.list_var)
return '%s = %s' % (', '.join(varz), handler_name)
- def _run(self, handler, output, namespace):
+ def _run(self, handler, context):
try:
- return self._run_and_set_variables(handler, output, namespace)
+ return self._run_and_set_variables(handler, context)
except DataError, err:
msg = unicode(err)
- output.fail(msg)
+ context.output.fail(msg)
raise ExecutionFailed(msg, syntax=True)
- def _run_and_set_variables(self, handler, output, namespace):
+ def _run_and_set_variables(self, handler, context):
try:
- return_value = Keyword._run(self, handler, output, namespace)
+ return_value = Keyword._run(self, handler, context)
except ExecutionFailed, err:
if err.cont:
- self._set_variables(namespace, output, None)
+ self._set_variables(context, None)
raise
- self._set_variables(namespace, output, return_value)
+ self._set_variables(context, return_value)
return return_value
- def _set_variables(self, namespace, output, return_value):
+ def _set_variables(self, context, return_value):
for name, value in self._get_vars_to_set(return_value):
- namespace.variables[name] = value
+ context.get_current_vars()[name] = value
if is_list_var(name) or utils.is_list(value):
value = utils.seq2str2(value)
else:
value = utils.unic(value)
- output.info('%s = %s' % (name,
utils.cut_long_assign_msg(value)))
+ context.output.info('%s = %s' % (name,
utils.cut_long_assign_msg(value)))
def _get_vars_to_set(self, ret):
if ret is None:
@@ -223,32 +222,32 @@
BaseKeyword.__init__(self, kwdata.name, type='for')
self.keywords = Keywords(kwdata.keywords)
- def run(self, output, namespace):
+ def run(self, context):
self.starttime = utils.get_timestamp()
- output.start_keyword(self)
+ context.output.start_keyword(self)
try:
- self._run(output, namespace)
+ self._run(context)
except ExecutionFailed, err:
error = err
except DataError, err:
msg = unicode(err)
- output.fail(msg)
+ context.output.fail(msg)
error = ExecutionFailed(msg, syntax=True)
else:
error = None
self.status = 'PASS' if not error else 'FAIL'
self.endtime = utils.get_timestamp()
self.elapsedtime = utils.get_elapsed_time(self.starttime,
self.endtime)
- output.end_keyword(self)
+ context.output.end_keyword(self)
if error:
raise error
- def _run(self, output, namespace):
- items = self._replace_vars_from_items(namespace.variables)
+ def _run(self, context):
+ items = self._replace_vars_from_items(context.get_current_vars())
errors = []
for i in range(0, len(items), len(self.vars)):
values = items[i:i+len(self.vars)]
- err = self._run_one_round(output, namespace, self.vars, values)
+ err = self._run_one_round(context, self.vars, values)
if err:
errors.extend(err.get_errors())
if not err.cont:
@@ -256,19 +255,19 @@
if errors:
raise ExecutionFailures(errors)
- def _run_one_round(self, output, namespace, variables, values):
+ def _run_one_round(self, context, variables, values):
foritem = ForItemKeyword(variables, values)
- output.start_keyword(foritem)
+ context.output.start_keyword(foritem)
for var, value in zip(variables, values):
- namespace.variables[var] = value
+ context.get_current_vars()[var] = value
try:
- self.keywords.run(output, namespace)
+ self.keywords.run(context)
except ExecutionFailed, err:
error = err
else:
error = None
foritem.end('PASS' if not error else 'FAIL')
- output.end_keyword(foritem)
+ context.output.end_keyword(foritem)
return error
def _replace_vars_from_items(self, variables):
@@ -314,12 +313,12 @@
BaseKeyword.__init__(self, kwdata.name, type='error')
self._error = kwdata.error
- def run(self, output, namespace):
+ def run(self, context):
self.starttime = utils.get_timestamp()
self.status = 'FAIL'
- output.start_keyword(self)
- output.fail(self._error)
+ context.output.start_keyword(self)
+ context.output.fail(self._error)
self.endtime = utils.get_timestamp()
self.elapsedtime = utils.get_elapsed_time(self.starttime,
self.endtime)
- output.end_keyword(self)
+ context.output.end_keyword(self)
raise ExecutionFailed(self._error, syntax=True)
=======================================
--- /trunk/src/robot/running/model.py Wed May 5 15:11:01 2010
+++ /trunk/src/robot/running/model.py Fri May 7 05:25:59 2010
@@ -35,6 +35,77 @@
return suite
+class ExecutionContext(object):
+
+ def __init__(self, namespace, output):
+ self.namespace = namespace
+ self.output = output
+
+ def get_current_vars(self):
+ return self.namespace.variables
+
+ def end_test(self, test):
+ self.output.end_test(test)
+ self.namespace.end_test()
+
+ def end_suite(self, suite):
+ self.output.end_suite(suite)
+ self.namespace.end_suite()
+
+ def output_file_changed(self, filename):
+ self._set_global_variable('${OUTPUT_FILE}', filename)
+
+ def replace_vars_from_setting(self, name, value, errors):
+ return self.namespace.variables.replace_meta(name, value, errors)
+
+ def log_file_changed(self, filename):
+ self._set_global_variable('${LOG_FILE}', filename)
+
+ def set_prev_test_variables(self, test):
+ self._set_prev_test_variables(self.get_current_vars(), test.name,
+ test.status, test.message)
+
+ def copy_prev_test_vars_to_global(self):
+ varz = self.get_current_vars()
+ name, status, message = varz['${PREV_TEST_NAME}'], \
+ varz['${PREV_TEST_STATUS}'],
varz['${PREV_TEST_MESSAGE}']
+ self._set_prev_test_variables(GLOBAL_VARIABLES, name, status,
message)
+
+ def _set_prev_test_variables(self, destination, name, status, message):
+ destination['${PREV_TEST_NAME}'] = name
+ destination['${PREV_TEST_STATUS}'] = status
+ destination['${PREV_TEST_MESSAGE}'] = message
+
+ def _set_global_variable(self, name, value):
+ self.namespace.variables.set_global(name, value)
+
+ def report_suite_status(self, status, message):
+ self.get_current_vars()['${SUITE_STATUS}'] = status
+ self.get_current_vars()['${SUITE_MESSAGE}'] = message
+
+ def start_test(self, test):
+ self.namespace.start_test(test)
+ self.output.start_test(test)
+
+ def set_test_status_before_teardown(self, message, status):
+ self.namespace.set_test_status_before_teardown(message, status)
+
+ def get_handler(self, name):
+ return self.namespace.get_handler(name)
+
+ def start_keyword(self, keyword):
+ self.output.start_keyword(keyword)
+
+ def end_keyword(self, keyword):
+ self.output.end_keyword(keyword)
+
+ def warn(self, message):
+ self.output.warn(message)
+
+ def trace(self, message):
+ self.output.trace(message)
+
+
class RunnableTestSuite(BaseTestSuite):
def __init__(self, data, testdefaults=None, parent=None):
@@ -58,56 +129,57 @@
self._run_mode_exit_on_failure = False
def run(self, output, parent=None, errors=None):
- self._start_run(output, parent, errors)
- self._run_setup(output)
- self._run_sub_suites(output)
- self._run_tests(output)
- self._report_status(output)
- self._run_teardown(output)
- self._end_run(output)
+ context = self._start_run(output, parent, errors)
+ self._run_setup(context)
+ self._run_sub_suites(context)
+ self._run_tests(context)
+ self._report_status(context)
+ self._run_teardown(context)
+ self._end_run(context)
def _start_run(self, output, parent, errors):
if not errors:
errors = SuiteRunErrors(self._run_mode_exit_on_failure)
self.run_errors = errors
self.run_errors.start_suite()
- self._init_run(parent)
- self._set_variable_dependent_metadata(self.namespace.variables)
- output.start_suite(self)
-
- def _init_run(self, parent):
self.status = 'RUNNING'
self.starttime = utils.get_timestamp()
- self.namespace = Namespace(self, parent)
- self.namespace.variables['${SUITE_NAME}'] = self.longname
- self.namespace.variables['${SUITE_SOURCE}'] = self.source
-
- def _set_variable_dependent_metadata(self, variables):
+ parent_vars = parent.context.get_current_vars() if parent else None
+ self.context = ExecutionContext(Namespace(self, parent_vars),
output)
+ self._set_variable_dependent_metadata(self.context)
+ output.start_suite(self)
+ return self.context
+
+ def _set_variable_dependent_metadata(self, context):
errors = []
- self.doc = variables.replace_meta('Documentation', self.doc,
errors)
- self.setup = Setup(variables.replace_meta('Setup', self.setup,
errors))
- self.teardown = Teardown(
- variables.replace_meta('Teardown', self.teardown, errors))
+ self.doc = context.replace_vars_from_setting('Documentation',
self.doc,
+ errors)
+ self.setup = Setup(context.replace_vars_from_setting('Setup',
self.setup,
+ errors))
+ self.teardown =
Teardown(context.replace_vars_from_setting('Teardown',
+
self.teardown,
+ errors))
for name, value in self.metadata.items():
- self.metadata[name] = variables.replace_meta(name, value,
errors)
+ self.metadata[name] = context.replace_vars_from_setting(name,
value,
+ errors)
if errors:
self.run_errors.suite_init_err('Suite initialization
failed:\n%s'
% '\n'.join(errors))
- def _run_setup(self, output):
+ def _run_setup(self, context):
if self.run_errors.is_suite_setup_allowed():
- self.setup.run(output, self.namespace,
SuiteSetupListener(self))
+ self.setup.run(context, SuiteSetupListener(self))
self.run_errors.setup_executed()
- def _run_teardown(self, output):
+ def _run_teardown(self, context):
if self.run_errors.is_suite_teardown_allowed():
- self.teardown.run(output, self.namespace,
SuiteTearDownListener(self))
-
- def _run_sub_suites(self, output):
+ self.teardown.run(context, SuiteTearDownListener(self))
+
+ def _run_sub_suites(self, context):
for suite in self.suites:
- suite.run(output, self, self.run_errors)
-
- def _run_tests(self, output):
+ suite.run(context.output, self, self.run_errors)
+
+ def _run_tests(self, context):
executed_tests = []
for test in self.tests:
normname = utils.normalize(test.name)
@@ -115,33 +187,21 @@
LOGGER.warn("Multiple test cases with name '%s' executed
in "
"test suite '%s'"% (test.name, self.longname))
executed_tests.append(normname)
- test.run(output, self.namespace, self.run_errors)
- self._set_prev_test_variables(self.namespace.variables, test)
-
- def _report_status(self, output):
+ test.run(context, self.run_errors)
+ context.set_prev_test_variables(test)
+
+ def _report_status(self, context):
self.set_status()
self.message = self.run_errors.suite_error()
- self.namespace.variables['${SUITE_STATUS}'] = self.status
- self.namespace.variables['${SUITE_MESSAGE}'] =
self.get_full_message()
-
- def _end_run(self, output):
+ context.report_suite_status(self.status, self.get_full_message())
+
+ def _end_run(self, context):
self.endtime = utils.get_timestamp()
self.elapsedtime = utils.get_elapsed_time(self.starttime,
self.endtime)
- self._set_prev_test_variables(GLOBAL_VARIABLES,
varz=self.namespace.variables)
- output.end_suite(self)
- self.namespace.end_suite()
+ context.copy_prev_test_vars_to_global()
+ context.end_suite(self)
self.run_errors.end_suite()
- def _set_prev_test_variables(self, destination, test=None, varz=None):
- if test:
- name, status, message = test.name, test.status, test.message
- else:
- name, status, message = varz['${PREV_TEST_NAME}'], \
- varz['${PREV_TEST_STATUS}'],
varz['${PREV_TEST_MESSAGE}']
- destination['${PREV_TEST_NAME}'] = name
- destination['${PREV_TEST_STATUS}'] = status
- destination['${PREV_TEST_MESSAGE}'] = message
-
class RunnableTestCase(BaseTestCase):
@@ -156,69 +216,74 @@
self.timeout = utils.get_not_none(data.timeout,
defaults.test_timeout)
self.keywords = Keywords(data.keywords)
- def run(self, output, namespace, suite_errors):
+ def run(self, context, suite_errors):
self._suite_errors = suite_errors
- self._start_run(output, namespace)
+ self._start_run(context)
if self.run_errors.is_allowed_to_run():
- self._run(output, namespace)
+ self._run(context)
else:
self._not_allowed_to_run()
- self._end_run(output, namespace)
-
- def _start_run(self, output, namespace):
+ self._end_run(context)
+
+ def _start_run(self, context):
self.run_errors = TestRunErrors(self._suite_errors)
self.status = 'RUNNING'
self.starttime = utils.get_timestamp()
- self.run_errors.init_err(self._init_test(namespace.variables))
- namespace.start_test(self)
- output.start_test(self)
-
- def _init_test(self, varz):
+ self.run_errors.init_err(self._init_test(context))
+ context.start_test(self)
+
+ def _init_test(self, context):
errors = []
- self.doc = varz.replace_meta('Documentation', self.doc, errors)
- self.setup = Setup(varz.replace_meta('Setup', self.setup, errors))
- self.teardown = Teardown(
- varz.replace_meta('Teardown', self.teardown, errors))
- self.tags = utils.normalize_tags(
- varz.replace_meta('Tags', self.tags, errors))
- self.timeout = TestTimeout(
- *varz.replace_meta('Timeout', self.timeout, errors))
+ self.doc = context.replace_vars_from_setting('Documentation',
self.doc,
+ errors)
+ self.setup = Setup(context.replace_vars_from_setting('Setup',
self.setup,
+ errors))
+ self.teardown =
Teardown(context.replace_vars_from_setting('Teardown',
+
self.teardown,
+ errors))
+ self.tags =
utils.normalize_tags(context.replace_vars_from_setting('Tags',
+
self.tags,
+
errors))
+ self.timeout =
TestTimeout(*context.replace_vars_from_setting('Timeout',
+
self.timeout,
+
errors))
if errors:
return 'Test case initialization
failed:\n%s' % '\n'.join(errors)
if not self.keywords:
return 'Test case contains no keywords'
-
- def _run(self, output, namespace):
+ return None
+
+ def _run(self, context):
self.timeout.start()
- self._run_setup(output, namespace)
+ self._run_setup(context)
if not self.run_errors.setup_failed():
try:
- self.keywords.run(output, namespace)
+ self.keywords.run(context)
except ExecutionFailed, err:
self.run_errors.kw_err(unicode(err))
self.keyword_failed(err)
- self._report_status(namespace)
- self._run_teardown(output, namespace)
+ context.set_test_status_before_teardown(*self._report_status())
+ self._run_teardown(context)
self._report_status_after_teardown()
def keyword_failed(self, err):
self.timeout.set_keyword_timeout(err.timeout)
self._suite_errors.test_failed(exit=err.exit)
- def _run_setup(self, output, namespace):
- self.setup.run(output, namespace, TestSetupListener(self))
-
- def _report_status(self, namespace):
+ def _run_setup(self, context):
+ self.setup.run(context, TestSetupListener(self))
+
+ def _report_status(self):
message = self.run_errors.get_message()
if message:
self.status = 'FAIL'
self.message = message
else:
self.status = 'PASS'
- namespace.test_ended(self.message, self.status)
-
- def _run_teardown(self, output, namespace):
- self.teardown.run(output, namespace, TestTeardownListener(self))
+ return self.message, self.status
+
+ def _run_teardown(self, context):
+ self.teardown.run(context, TestTeardownListener(self))
def _report_status_after_teardown(self):
if self.run_errors.teardown_failed():
@@ -234,11 +299,10 @@
self.status = 'FAIL'
self.message = self.run_errors.parent_or_init_error()
- def _end_run(self, output, namespace):
+ def _end_run(self, context):
self.endtime = utils.get_timestamp()
self.elapsedtime = utils.get_elapsed_time(self.starttime,
self.endtime)
- output.end_test(self)
- namespace.end_test()
+ context.end_test(self)
class _TestCaseDefaults:
=======================================
--- /trunk/src/robot/running/namespace.py Wed May 5 01:04:16 2010
+++ /trunk/src/robot/running/namespace.py Fri May 7 05:25:59 2010
@@ -36,10 +36,10 @@
A new instance of this class is created for each test suite.
"""
- def __init__(self, suite, parent):
+ def __init__(self, suite, parent_vars):
if suite is not None:
LOGGER.info("Initializing namespace for test suite '%s'" %
suite.longname)
- self.variables = _VariableScopes(suite, parent)
+ self.variables = _VariableScopes(suite, parent_vars)
self.suite = suite
self.test = None
self.uk_handlers = []
@@ -54,6 +54,8 @@
if suite.source is not None:
self._handle_imports(suite.imports)
robot.running.NAMESPACES.start_suite(self)
+ self.variables['${SUITE_NAME}'] = suite.longname
+ self.variables['${SUITE_SOURCE}'] = suite.source
def _handle_imports(self, import_settings):
for item in import_settings:
@@ -149,7 +151,7 @@
for lib in self._testlibs.values():
lib.end_test()
- def test_ended(self, message, status):
+ def set_test_status_before_teardown(self, message, status):
self.variables['${TEST_MESSAGE}'] = message
self.variables['${TEST_STATUS}'] = status
@@ -297,15 +299,15 @@
class _VariableScopes:
- def __init__(self, suite, parent):
+ def __init__(self, suite, parent_vars):
# suite and parent are None only when used by copy_all
if suite is not None:
suite.variables.update(GLOBAL_VARIABLES)
self._suite = self.current = suite.variables
self._parents = []
- if parent is not None:
- self._parents.append(parent.namespace.variables.current)
- self._parents.extend(parent.namespace.variables._parents)
+ if parent_vars is not None:
+ self._parents.append(parent_vars.current)
+ self._parents.extend(parent_vars._parents)
self._test = None
self._uk_handlers = []
@@ -351,6 +353,7 @@
def set_from_variable_table(self, rawvariables):
self._suite.set_from_variable_table(rawvariables)
+ # TODO Cleanup, accumulator and return val etc.
def replace_meta(self, name, item, errors):
error = None
for varz in [self.current] + self._parents:
=======================================
--- /trunk/src/robot/running/userkeyword.py Tue May 4 04:28:08 2010
+++ /trunk/src/robot/running/userkeyword.py Fri May 7 05:25:59 2010
@@ -124,27 +124,28 @@
self._timeout = metadata.get('Timeout', [])
self.timeout = [ utils.unescape(item) for item in self._timeout ]
- def init_user_keyword(self, varz):
+ def init_keyword(self, varz):
self._errors = []
self.doc = varz.replace_meta('Documentation', self._doc,
self._errors)
timeout = varz.replace_meta('Timeout', self._timeout, self._errors)
self.timeout = KeywordTimeout(*timeout)
- def run(self, output, namespace, arguments):
- namespace.start_user_keyword(self)
+ def run(self, context, arguments):
+ context.namespace.start_user_keyword(self)
try:
- return self._run(output, namespace, arguments)
+ return self._run(context, arguments)
finally:
- namespace.end_user_keyword()
-
- def _run(self, output, namespace, arguments):
- argument_values = self.arguments.resolve(arguments,
namespace.variables)
- self.arguments.set_variables(argument_values, namespace.variables,
- output)
+ context.namespace.end_user_keyword()
+
+ def _run(self, context, arguments):
+ variables = context.get_current_vars()
+ argument_values = self.arguments.resolve(arguments, variables)
+ output = context.output
+ self.arguments.set_variables(argument_values, variables, output)
self._verify_keyword_is_valid()
self.timeout.start()
- self.keywords.run(output, namespace)
- return self._get_return_value(namespace.variables)
+ self.keywords.run(context)
+ return self._get_return_value(variables)
def _verify_keyword_is_valid(self):
if self._errors:
@@ -205,10 +206,10 @@
self.origname = template.name
self._copy_attrs_from_template(template)
- def run(self, output, namespace, args):
+ def run(self, context, args):
for name, value in self.embedded_args:
- namespace.variables[name] =
namespace.variables.replace_scalar(value)
- return UserKeywordHandler.run(self, output, namespace, args)
+ context.get_current_vars()[name] =
context.get_current_vars().replace_scalar(value)
+ return UserKeywordHandler.run(self, context, args)
def _copy_attrs_from_template(self, template):
self._libname = template._libname
=======================================
--- /trunk/utest/running/test_keywords.py Thu May 6 00:18:21 2010
+++ /trunk/utest/running/test_keywords.py Fri May 7 05:25:59 2010
@@ -26,7 +26,9 @@
self.error = error
self.timeout = KeywordTimeout()
- def run(self, output, namespace, args):
+ def init_keyword(self, varz): pass
+
+ def run(self, context, args):
"""Sets given args to self.ags and optionally returns something.
Returning works so that if two args are given and the first one is
@@ -45,14 +47,28 @@
class FakeNamespace(_FakeNamespace):
- def __init__(self, error=False):
+ def __init__(self):
_FakeNamespace.__init__(self)
- self.error = error
self.suite = _FakeSuite()
+
+class _FakeContext(object):
+ def __init__(self, error=False):
+ self.namespace = FakeNamespace()
+ self.output = OutputStub()
+ self.error = error
+ self.variables = self.namespace.variables
+
def get_handler(self, kwname):
return MockHandler('Mocked.'+kwname, error=self.error)
+ def get_current_vars(self):
+ return self.namespace.variables
+
+ def start_keyword(self, kw): pass
+ def end_keyword(self, kw): pass
+ def trace(self, msg): pass
+
class TestKeyword(unittest.TestCase):
@@ -71,13 +87,13 @@
def test_run_error(self):
kw = Keyword('handler_name', ())
- assert_raises(ExecutionFailed, kw.run, OutputStub(),
FakeNamespace(error=True))
+ assert_raises(ExecutionFailed, kw.run, _FakeContext(error=True))
def _verify_run(self, args):
kw = Keyword('handler_name', args)
assert_equals(kw.name, 'handler_name')
assert_equals(kw.args, args)
- kw.run(OutputStub(), FakeNamespace())
+ kw.run(_FakeContext())
assert_equals(kw.name, 'Mocked.handler_name')
assert_equals(kw.doc, 'Mock Doc')
assert_equals(kw.handler_name, 'handler_name')
@@ -121,89 +137,89 @@
def test_set_string_to_scalar(self):
skw = SetKeyword(SetKeywordData(['${var}','KW','RETURN','value']))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['${var}'], 'value')
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['${var}'], 'value')
def test_set_object_to_scalar(self):
skw = SetKeyword(SetKeywordData(['${var}','KW','RETURN',self]))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['${var}'], self)
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['${var}'], self)
def test_set_empty_list_to_scalar(self):
skw = SetKeyword(SetKeywordData(['${var}','KW','RETURN',[]]))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['${var}'], [])
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['${var}'], [])
def test_set_list_with_one_element_to_scalar(self):
skw = SetKeyword(SetKeywordData(['${var}','KW','RETURN',['hi']]))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['${var}'], ['hi'])
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['${var}'], ['hi'])
def test_set_strings_to_three_scalars(self):
skw =
SetKeyword(SetKeywordData(['${v1}','${v2}','${v3}','KW','RETURN',['x','y','z']]))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['${v1}'], 'x')
- assert_equal(namespace.variables['${v2}'], 'y')
- assert_equal(namespace.variables['${v3}'], 'z')
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['${v1}'], 'x')
+ assert_equal(context.variables['${v2}'], 'y')
+ assert_equal(context.variables['${v3}'], 'z')
def test_set_objects_to_three_scalars(self):
skw =
SetKeyword(SetKeywordData(['${v1}','${v2}','${v3}','KW','RETURN',[['x','y'],{},None]]))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['${v1}'], ['x','y'])
- assert_equal(namespace.variables['${v2}'], {})
- assert_equal(namespace.variables['${v3}'], None)
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['${v1}'], ['x','y'])
+ assert_equal(context.variables['${v2}'], {})
+ assert_equal(context.variables['${v3}'], None)
def test_set_list_of_strings_to_list(self):
skw =
SetKeyword(SetKeywordData(['@{var}','KW','RETURN',['x','y','z']]))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['@{var}'], ['x','y','z'])
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['@{var}'], ['x','y','z'])
def test_set_empty_list_to_list(self):
skw = SetKeyword(SetKeywordData(['@{var}','KW','RETURN',[]]))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['@{var}'], [])
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['@{var}'], [])
def test_set_objects_to_two_scalars_and_list(self):
skw =
SetKeyword(SetKeywordData(['${v1}','${v2}','@{v3}','KW','RETURN',['a',None,'x','y',{}]]))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['${v1}'], 'a')
- assert_equal(namespace.variables['${v2}'], None)
- assert_equal(namespace.variables['@{v3}'], ['x','y',{}])
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['${v1}'], 'a')
+ assert_equal(context.variables['${v2}'], None)
+ assert_equal(context.variables['@{v3}'], ['x','y',{}])
def test_set_scalars_and_list_so_that_list_is_empty(self):
skw =
SetKeyword(SetKeywordData(['${scal}','@{list}','KW','RETURN',['a']]))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['${scal}'], 'a')
- assert_equal(namespace.variables['@{list}'], [])
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['${scal}'], 'a')
+ assert_equal(context.variables['@{list}'], [])
def test_set_more_values_than_variables(self):
skw =
SetKeyword(SetKeywordData(['${v1}','${v2}','KW','RETURN',['x','y','z']]))
- namespace = FakeNamespace()
- skw.run(OutputStub(), namespace)
- assert_equal(namespace.variables['${v1}'], 'x')
- assert_equal(namespace.variables['${v2}'], ['y','z'])
+ context = _FakeContext()
+ skw.run(context)
+ assert_equal(context.variables['${v1}'], 'x')
+ assert_equal(context.variables['${v2}'], ['y','z'])
def test_set_too_few_scalars_raises(self):
skw =
SetKeyword(SetKeywordData(['${v1}','${v2}','KW','RETURN',['x']]))
- assert_raises(ExecutionFailed, skw.run, OutputStub(),
FakeNamespace())
+ assert_raises(ExecutionFailed, skw.run, _FakeContext())
def test_set_list_but_no_list_raises(self):
skw = SetKeyword(SetKeywordData(['@{list}','KW','RETURN','not a
list']))
- assert_raises(ExecutionFailed, skw.run, OutputStub(),
FakeNamespace())
+ assert_raises(ExecutionFailed, skw.run, _FakeContext())
def test_set_too_few_scalars_with_list_raises(self):
skw =
SetKeyword(SetKeywordData(['${v1}','${v2}','@{list}','KW','RETURN',['x']]))
- assert_raises(ExecutionFailed, skw.run, OutputStub(),
FakeNamespace())
+ assert_raises(ExecutionFailed, skw.run, _FakeContext())
if __name__ == '__main__':
=======================================
--- /trunk/utest/running/test_testlibrary.py Thu Apr 15 04:56:53 2010
+++ /trunk/utest/running/test_testlibrary.py Fri May 7 05:25:59 2010
@@ -397,7 +397,7 @@
lib = TestLibrary('classes.RecordingLibrary')
calls_after_init = lib._libinst.calls_to_getattr
for _ in range(5):
- lib.handlers['kw'].run(_FakeOutput(), _FakeNamespace(), [])
+ lib.handlers['kw'].run(_FakeContext(), [])
assert_equals(lib._libinst.calls_to_getattr, calls_after_init)
if utils.is_jython:
@@ -506,5 +506,14 @@
pass
+class _FakeContext:
+ def __init__(self):
+ self.output = _FakeOutput()
+ self.namespace = _FakeNamespace()
+
+ def get_current_vars(self):
+ return self.namespace.variables
+
+
if __name__ == '__main__':
unittest.main()