Revision: 3899
Author: jussi.ao.malinen
Date: Wed Aug 25 03:05:46 2010
Log: Exit For Loop keyword. Still missing doc string and possible refactoring.
http://code.google.com/p/robotframework/source/detail?r=3899

Added:
 /trunk/atest/robot/core/exit_for_loop.txt
 /trunk/atest/testdata/core/exit_for_loop.txt
Modified:
 /trunk/src/robot/errors.py
 /trunk/src/robot/libraries/BuiltIn.py
 /trunk/src/robot/running/keywords.py

=======================================
--- /dev/null
+++ /trunk/atest/robot/core/exit_for_loop.txt   Wed Aug 25 03:05:46 2010
@@ -0,0 +1,49 @@
+*** Settings ***
+Suite Setup     Run Tests  ${EMPTY}  core/exit_for_loop.txt
+Force Tags      regression  pybot  jybot
+Resource        atest_resource.txt
+
+*** Test Cases ***
+
+Simple Exit For Loop
+    Test And All Keywords Should Have Passed
+
+Exit For Loop In Runkeyword
+    Test And All Keywords Should Have Passed
+
+Exit For Loop In UserKeyword
+    Test And All Keywords Should Have Passed
+
+Exit For Loop In UserKeyword With Loop
+    Test And All Keywords Should Have Passed
+
+Exit For Loop In UserKeyword With Loop Within Loop
+    Test And All Keywords Should Have Passed
+
+Exit For Loop In Userkeyword Calling Userkeyword With Exit For Loop
+    Test And All Keywords Should Have Passed
+
+Exit For Loop Without For Loop Should Fail
+    Check Test Case  ${TESTNAME}
+
+Exit For Loop In Userkeyword Without For Loop Should Fail
+    Check Test Case  ${TESTNAME}
+
+Exit For Loop Keyword Should Have No Messages
+    ${tc} =  Check Test Case  Simple Exit For Loop
+    Should Be Equal  ${tc.kws[0].kws[0].kws[0].name}  BuiltIn.Exit For Loop
+    Should Be Empty  ${tc.kws[0].kws[0].kws[0].msgs}
+
+*** Keyword ***
+Test And All Keywords Should Have Passed
+    ${tc} =  Check Test Case  ${TESTNAME}
+    Check All Keywords Passed  ${tc}
+    Should Be Equal  ${tc.kws[-1].name}  BuiltIn.Should Be Equal
+
+
+Check All Keywords Passed
+    [arguments]  ${tc or kw}
+    @{kws} =  Set Variable  ${tc or kw.kws}
+    :FOR  ${kw}  IN  @{kws}
+    \    Should Be Equal  ${kw.status}  PASS
+    \    Check All Keywords Passed  ${kw}
=======================================
--- /dev/null
+++ /trunk/atest/testdata/core/exit_for_loop.txt        Wed Aug 25 03:05:46 2010
@@ -0,0 +1,71 @@
+*** Test Cases ***
+Simple Exit For Loop
+    :FOR  ${var}  IN  one  two
+    \  Exit For Loop
+    \  Fail  Should not be executed
+    Should BE Equal  ${var}  one
+
+Exit For Loop In Runkeyword
+    :FOR  ${var}  IN  one  two  three
+    \  Run Keyword If  '${var}' == 'two'  Exit For Loop
+    \  ${x} =  Set Variable  ${var}-extra
+    Should Be Equal  ${x}  one-extra
+    Should Be Equal  ${var}  two
+
+Exit For Loop In UserKeyword
+    :FOR  ${var}  IN  one  two
+    \  With Only Exit For Loop
+    \  Fail  Should not be executed
+    Should BE Equal  ${var}  one
+
+Exit For Loop In UserKeyword With Loop
+    :FOR  ${var}  IN  one  two
+    \  With Loop
+    \  ${x} =  Set Variable  ${var}-extra
+    Should Be Equal  ${x}  two-extra
+
+Exit For Loop In UserKeyword With Loop Within Loop
+    :FOR  ${var}  IN  one  two
+    \  With Loop Within Loop
+    \  ${x} =  Set Variable  ${var}-extra
+    Should Be Equal  ${x}  two-extra
+
+Exit For Loop In Userkeyword Calling Userkeyword With Exit For Loop
+    :FOR  ${var}  IN  one  two
+    \  With Keyword For Loop Calling Keyword With Exit For Loop
+    \  ${x} =  Set Variable  ${var}-extra
+    Should Be Equal  ${x}  two-extra
+
+Exit For Loop Without For Loop Should Fail
+   [Documentation]  FAIL Exit for loop without enclosing for loop.
+   Exit For Loop
+
+Exit For Loop In Userkeyword Without For Loop Should Fail
+   [Documentation]  FAIL Exit for loop without enclosing for loop.
+   With Only Exit For Loop
+
+
+*** Keyword ***
+With Loop
+    :FOR  ${var}  IN  one  two
+    \  Exit For Loop
+    \  Fail
+    Log  KW Finished
+
+With Only Exit For Loop
+    Exit For Loop
+    Fail
+
+With Loop Within Loop
+    :FOR  ${var}  IN  one  two
+    \  With Loop
+    \  Log  This is Logged
+    \  Exit For Loop
+    \  Fail
+    Log  Loop Within Loop Finished
+
+With Keyword For Loop Calling Keyword With Exit For Loop
+    :FOR  ${var}  IN  one  two
+    \  With Only Exit For Loop
+    \  Fail
+    Log  This Is Logged
=======================================
--- /trunk/src/robot/errors.py  Wed Aug 18 04:02:26 2010
+++ /trunk/src/robot/errors.py  Wed Aug 25 03:05:46 2010
@@ -73,12 +73,13 @@
     """Used for communicating failures in test execution."""

     def __init__(self, message, timeout=False, syntax=False, exit=False,
-                 cont=False):
+                 cont=False, exit_for_loop=False):
         RobotError.__init__(self, utils.cut_long_message(message))
         self.timeout = timeout
         self.syntax = syntax
         self.exit = exit
         self.cont = cont
+        self.exit_for_loop = exit_for_loop

     @property
     def dont_cont(self):
@@ -110,8 +111,9 @@
         syntax = isinstance(orig_error, DataError)
         exit = bool(getattr(orig_error, 'ROBOT_EXIT_ON_FAILURE', False))
cont = bool(getattr(orig_error, 'ROBOT_CONTINUE_ON_FAILURE', False)) + exit_for_loop = bool(getattr(orig_error, 'ROBOT_EXIT_FOR_LOOP', False)) ExecutionFailed.__init__(self, error_details.message, timeout, syntax,
-                                 exit, cont)
+                                 exit, cont, exit_for_loop)


 class ExecutionFailures(ExecutionFailed):
@@ -121,7 +123,8 @@
                                  any(err.timeout for err in errors),
                                  any(err.syntax for err in errors),
                                  any(err.exit for err in errors),
-                                 all(err.cont for err in errors))
+                                 all(err.cont for err in errors),
+                                 all(err.exit_for_loop for err in errors))
         self._errors = errors

     def _format_message(self, errors):
=======================================
--- /trunk/src/robot/libraries/BuiltIn.py       Mon Aug 23 00:45:43 2010
+++ /trunk/src/robot/libraries/BuiltIn.py       Wed Aug 25 03:05:46 2010
@@ -140,6 +140,14 @@
         error.ROBOT_EXIT_ON_FAILURE = True
         raise error

+    def exit_for_loop(self):
+        """TODO
+        """
+        # Error message is shown only if there is no eclosing for loop
+        error = AssertionError('Exit for loop without enclosing for loop.')
+        error.ROBOT_EXIT_FOR_LOOP = True
+        raise error
+
     def should_not_be_true(self, condition, msg=None):
         """Fails if the given condition is true.

=======================================
--- /trunk/src/robot/running/keywords.py        Fri Aug 20 06:02:44 2010
+++ /trunk/src/robot/running/keywords.py        Wed Aug 25 03:05:46 2010
@@ -73,7 +73,7 @@
         try:
             return_value = self._run(handler, context)
         except ExecutionFailed, err:
-            self.status = 'FAIL'
+            self.status = 'FAIL' if not err.exit_for_loop else 'PASS'
             self._end(context, error=err)
             raise
         else:
@@ -128,11 +128,14 @@
             raise ExecutionFailed(msg, syntax=True)

     def _report_failure(self, context):
+        # TODO: Refactor
         error_details = utils.ErrorDetails()
-        context.output.fail(error_details.message)
-        if error_details.traceback:
-            context.output.debug(error_details.traceback)
-        raise HandlerExecutionFailed(error_details)
+        error = HandlerExecutionFailed(error_details)
+        if not error.exit_for_loop:
+            context.output.fail(error_details.message)
+            if error_details.traceback:
+                context.output.debug(error_details.traceback)
+        raise error


 class _VariableAssigner(object):
@@ -293,6 +296,8 @@
             values = items[i:i+len(self.vars)]
             err = self._run_one_round(context, self.vars, values)
             if err:
+                if err.exit_for_loop:
+                    break
                 errors.extend(err.get_errors())
                 if not err.can_continue(context.teardown, self._templated,
                                         context.dry_run):
@@ -317,7 +322,7 @@
             error = err
         else:
             error = None
-        foritem.end('PASS' if not error else 'FAIL')
+        foritem.end('PASS' if not error or error.exit_for_loop else 'FAIL')
         context.output.end_keyword(foritem)
         return error

Reply via email to