Revision: 3112
Author: janne.t.harkonen
Date: Mon May  3 00:10:16 2010
Log: Handle continuable errors properly in user keywords, cleanup
http://code.google.com/p/robotframework/source/detail?r=3112

Modified:
 /trunk/src/robot/running/model.py
 /trunk/src/robot/running/runerrors.py
 /trunk/src/robot/running/userkeyword.py

=======================================
--- /trunk/src/robot/running/model.py   Fri Apr 30 04:09:21 2010
+++ /trunk/src/robot/running/model.py   Mon May  3 00:10:16 2010
@@ -213,15 +213,16 @@
         namespace.variables['@{TEST_TAGS}'] = self.tags

     def _run_setup(self, output, namespace):
-        setup_err = self._run_fixture(self.setup, output, namespace)
-        self._run_errors.setup_err(setup_err)
+        error = self._run_fixture(self.setup, output, namespace)
+        if error:
+            self._run_errors.setup_err(error.msg)

     def _run_keywords(self, output, namespace):
         for kw in self.keywords:
- kw_err, can_continue = self._run_with_error_handling(kw, output, namespace)
-            if kw_err:
-                self._run_errors.kw_err(kw_err)
-                if not can_continue:
+            error = self._run_with_error_handling(kw, output, namespace)
+            if error:
+                self._run_errors.kw_err(error.msg)
+                if not error.cont:
                     return

     def _report_status(self, namespace):
@@ -231,8 +232,9 @@
         namespace.variables['${TEST_STATUS}'] = self.status

     def _run_teardown(self, output, namespace):
-        td_err = self._run_fixture(self.teardown, output, namespace)
-        self._run_errors.teardown_err(td_err)
+        error = self._run_fixture(self.teardown, output, namespace)
+        if error:
+            self._run_errors.teardown_err(error.msg)

     def _report_status_after_teardown(self):
         if self._run_errors.teardown_failed():
@@ -256,16 +258,16 @@

     def _run_fixture(self, fixture, output, namespace):
         if fixture:
- return self._run_with_error_handling(fixture, output, namespace)[0] + return self._run_with_error_handling(fixture, output, namespace)

     def _run_with_error_handling(self, runnable, output, namespace):
         try:
             runnable.run(output, namespace)
-            return '', True
+            return None
         except ExecutionFailed, err:
             self.timeout.set_keyword_timeout(err.timeout)
             self._suite_errors.test_failed(exit=err.exit)
-            return err.msg, err.cont
+            return err


 class _TestCaseDefaults:
=======================================
--- /trunk/src/robot/running/runerrors.py       Fri Apr 30 04:09:21 2010
+++ /trunk/src/robot/running/runerrors.py       Mon May  3 00:10:16 2010
@@ -138,14 +138,7 @@
     def get_message(self):
         if self._setup_err:
             return 'Setup failed:\n%s' % self._setup_err
-        if len(self._kw_errs) > 0:
-            if len(self._kw_errs) > 1:
-                errors = [ 'Error %d: %s' % (i+1, err)
-                           for i, err in enumerate(self._kw_errs) ]
-            else:
-                errors = self._kw_errs
-            return '\n\n'.join(errors)
-        return ''
+        return _form_error_message(self._kw_errs)

     def get_teardown_message(self, message):
         if message == '':
@@ -154,3 +147,24 @@

     def parent_or_init_error(self):
         return self._parent_err or self._init_err
+
+
+class UserKeywordRunErrors(object):
+
+    def __init__(self):
+        self._errors = []
+
+    def add(self, msg):
+        self._errors.append(msg)
+
+    def has_errors(self):
+        return bool(self._errors)
+
+    def get_message(self):
+        return _form_error_message(self._errors)
+
+
+def _form_error_message(errors):
+ """Returns list of errors formatted as a string (empty string is returned if list is empty)""" + return '\n\n'.join(errors if len(errors) == 1 else [ 'Error %d: %s' % (i+1, err) + for i, err in enumerate(errors) ])
=======================================
--- /trunk/src/robot/running/userkeyword.py     Fri Apr 30 04:09:21 2010
+++ /trunk/src/robot/running/userkeyword.py     Mon May  3 00:10:16 2010
@@ -23,6 +23,7 @@
 from keywords import KeywordFactory
 from timeouts import KeywordTimeout
 from arguments import UserKeywordArguments
+from runerrors import UserKeywordRunErrors


 def PublicUserLibrary(path):
@@ -49,7 +50,7 @@
                 try:
                     handler = EmbeddedArgsTemplate(handler, self.name)
                 except TypeError:
-                    handler = UserHandler(handler, self.name)
+                    handler = UserKeywordHandler(handler, self.name)
                 else:
                     self.embedded_arg_handlers.append(handler)
             if self.handlers.has_key(handler.name):
@@ -99,13 +100,12 @@
                         "Found: %s" % (where, name, names))


-class UserHandler(object):
+class UserKeywordHandler(object):
     type = 'user'
     longname = property(lambda self: not self._libname and self.name
                         or '%s.%s' % (self._libname, self.name))
shortdoc = property(lambda self: self.doc.splitlines()[0] if self.doc else '')

-
     def __init__(self, handlerdata, libname):
         self.name = utils.printable_name(handlerdata.name)
         self._libname = libname
@@ -141,23 +141,14 @@
     def _run(self, output, namespace, arguments):
argument_values = self.arguments.resolve(arguments, namespace.variables)
         self.arguments.set_variables(argument_values, namespace.variables,
-                                      output)
+                                     output)
         self._verify_keyword_is_valid()
         self.timeout.start()
-        errors = []
+        self._errors = UserKeywordRunErrors()
         for kw in self.keywords:
-            try:
-                kw.run(output, namespace)
-            except ExecutionFailed, err:
-                if not err.cont:
-                    raise
-                else:
-                    errors.append(err.msg)
-        if errors:
-            if len(errors) > 1:
-                errors = [ 'Error %d: %s' % (i+1, err)
-                           for i, err in enumerate(errors) ]
-            raise ExecutionFailed('\n\n'.join(errors))
+            self._run_with_error_handling(kw, output, namespace)
+        if self._errors.has_errors():
+            raise ExecutionFailed(self._errors.get_message(), cont=True)
         return self._get_return_value(namespace.variables)

     def _verify_keyword_is_valid(self):
@@ -168,6 +159,14 @@
             raise DataError("User keyword '%s' contains no keywords"
                             % self.name)

+    def _run_with_error_handling(self, kw, output, namespace):
+        try:
+            kw.run(output, namespace)
+        except ExecutionFailed, err:
+            self._errors.add(err.msg)
+            if not err.cont:
+                raise ExecutionFailed(self._errors.get_message())
+
     def _get_return_value(self, variables):
         if not self.return_value:
             return None
@@ -177,7 +176,7 @@
         return ret[0]


-class EmbeddedArgsTemplate(UserHandler):
+class EmbeddedArgsTemplate(UserKeywordHandler):

     def __init__(self, handlerdata, libname):
         if handlerdata.args:
@@ -186,7 +185,7 @@
                 = self._read_embedded_args_and_regexp(handlerdata.name)
         if not self.embedded_args:
             raise TypeError('Must have embedded arguments')
-        UserHandler.__init__(self, handlerdata, libname)
+        UserKeywordHandler.__init__(self, handlerdata, libname)

     def _read_embedded_args_and_regexp(self, string):
         args = []
@@ -208,7 +207,7 @@
return string[:var.start], string[var.start:var.end], string[var.end:]


-class EmbeddedArgs(UserHandler):
+class EmbeddedArgs(UserKeywordHandler):

     def __init__(self, name, template):
         match = template.name_regexp.match(name)
@@ -222,7 +221,7 @@
     def run(self, output, namespace, args):
         for name, value in self.embedded_args:
namespace.variables[name] = namespace.variables.replace_scalar(value)
-        return UserHandler.run(self, output, namespace, args)
+        return UserKeywordHandler.run(self, output, namespace, args)

     def _copy_attrs_from_template(self, template):
         self._libname = template._libname

Reply via email to