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