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()

Reply via email to