Revision: 4482
Author: jprantan
Date: Thu Dec  9 06:33:36 2010
Log: Implementation to automatically handle removed x times syntax. Issue 731.
http://code.google.com/p/robotframework/source/detail?r=4482

Added:
 /trunk/atest/robot/keywords/repeating_keyword.txt
 /trunk/atest/testdata/keywords/repeating_keyword.txt
Modified:
 /trunk/src/robot/running/handlers.py
 /trunk/src/robot/running/namespace.py

=======================================
--- /dev/null
+++ /trunk/atest/robot/keywords/repeating_keyword.txt Thu Dec 9 06:33:36 2010
@@ -0,0 +1,140 @@
+*** Settings ***
+Documentation This feature has been depreaced in 2.0.4 and will be removed in 2.2. See issue 193 for more information.
+Suite Setup     Run Tests  ${EMPTY}  keywords/repeating_keyword.txt
+Force Tags      regression  smoke  jybot  pybot
+Resource        atest_resource.txt
+
+*** Test Cases ***
+Repeat Keyword Name and Arguments
+    ${test} =  Check Test Case  Repeat Doing Nothing
+    Verify Deprecation Messages  ${test.kws[0].msgs[0]}  1 x
+    Verify Deprecation Messages  ${test.kws[1].msgs[0]}  1000x
+    Equals  ${test.kws[0].name}  1 x
+    Equals  ${test.kws[1].name}  1000x
+    ${test} =  Check Test Case  Repeat With Arguments Doing Nothing
+    Verify Deprecation Messages  ${test.kws[0].msgs[0]}  1 x
+    Equals  ${test.kws[0].name}  1 x
+    Fail Unless  ${test.kws[0].args} == ['Comment', 'Nothing is done']
+    Verify Deprecation Messages  ${test.kws[1].msgs[0]}  42 X
+    Equals  ${test.kws[1].name}  42 X
+    Fail Unless  ${test.kws[1].args} == ['Comment', 'Still', 'nothing']
+
+Repeat Keyword Messages
+    ${test} =  Check Test Case  Repeat With Messages
+    Verify Deprecation Messages  ${test.kws[0].msgs[0]}  1 x
+    Check Log Message  ${test.kws[0].msgs[1]}  Repeating keyword, round 1/1
+    Check Log Message  ${test.kws[0].kws[0].msgs[0]}  Hello, world
+    Verify Deprecation Messages  ${test.kws[1].msgs[0]}  33 x
+    Check Log Message  ${test.kws[1].kws[0].msgs[0]}  Hi, tellus
+    Check Log Message  ${test.kws[1].kws[2].msgs[0]}  Hi, tellus
+    Check Log Message  ${test.kws[1].kws[3].msgs[0]}  Hi, tellus
+    Check Log Message  ${test.kws[1].kws[32].msgs[0]}  Hi, tellus
+
+Repeating User Keyword
+    ${test} =  Check Test Case  Repeating User Keyword
+    ${kws} =  Set  ${test.keywords}
+    Verify Deprecation Messages  ${kws[0].msgs[0]}  1 x
+ Check Log Message ${kws[0].kws[0].kws[0].msgs[0]} Hello from Repeating UK
+    Check Log Message  ${kws[0].kws[0].kws[1].msgs[0]}  Yo, world
+ Check Log Message ${kws[1].kws[0].kws[0].msgs[0]} Hello from Repeating UK
+    Check Log Message  ${kws[1].kws[0].kws[1].msgs[0]}  Yo, tellus
+ Check Log Message ${kws[1].kws[1].kws[0].msgs[0]} Hello from Repeating UK
+    Check Log Message  ${kws[1].kws[1].kws[1].msgs[0]}  Yo, tellus
+    ${kws} =  Set  ${kws[2].keywords}
+ Check Log Message ${kws[0].kws[0].kws[0].msgs[0]} Hello from Repeating UK
+    Check Log Message  ${kws[0].kws[0].kws[1].msgs[0]}  Sub kw
+
+Repeating Inside User Keyword
+    ${test} =  Check Test Case  Repeating Inside User Keyword
+    Test Repeating Inside UK  ${test.kws[0].kws[0]}
+
+Repeating Inside Repeating
+    ${test} =  Check Test Case  Repeating Inside Repeating
+    Test Repeating Inside UK  ${test.kws[0].kws[0]}
+    Test Repeating Inside UK  ${test.kws[0].kws[1]}
+    Test Repeating Inside UK  ${test.kws[0].kws[2]}
+    Test Repeating Inside UK  ${test.kws[0].kws[3]}
+
+Failing Repeat Keyword
+    ${test} =  Check Test Case  Failing Repeat Keyword
+ Check Log Message ${test.kws[0].msgs[1]} Failing instead of repeating FAIL
+    ${test} =  Check Test Case  Not First Repeat Keyword Failing
+    Check Log Message  ${test.kws[0].kws[0].msgs[0]}  \${limit} = 9
+    Check Log Message  ${test.kws[0].kws[3].msgs[0]}  \${limit} = 8
+    Check Log Message  ${test.kws[0].kws[6].msgs[0]}  \${limit} = 7
+    Check Log Message  ${test.kws[0].kws[27].msgs[0]}  \${limit} = 0
+ Check Log Message ${test.kws[0].kws[29].msgs[0]} Recursion limit exceeded FAIL
+    ${test} =  Check Test Case  Failing Repeat Keyword and Teardown
+ Check Log Message ${test.kws[0].msgs[1]} Failing, again, instead of repeating FAIL
+    ${test} =  Check Test Case  Non-Exising Variable In Repeat Keyword
+ Check Log Message ${test.kws[0].msgs[1]} Non-existing variable '\${non-exiting-variable}' FAIL
+
+Non Existing Keyword In Repeat
+    Check Test Case  Non Existing Keyword In Repeat
+
+Zero Repeat
+    [Documentation]  Zero repeat means not executing the keyword at all
+    ${test} =  Check Test Case  Zero Repeat
+    Equals  ${test.kws[0].name}  0x BuiltIn.Fail
+
+Negative Repeat
+    [Documentation]  Negative repeat is the same as zero repeat
+    ${test} =  Check Test Case  Negative Repeat
+    Equals  ${test.kws[0].name}  -1x BuiltIn.Fail
+
+Repeat With Valid Int Variable
+    ${test} =  Check Test Case  Repeat With Valid Int Variable
+    Verify Deprecation Messages  ${test.kws[0].msgs[0]}  \${3} x
+    Equals  ${test.kws[0].name}  3x BuiltIn.Log
+    Check Log Message  ${test.kws[0].msgs[1]}  Repeated 3 times
+    Check Log Message  ${test.kws[0].msgs[2]}  Repeated 3 times
+    Check Log Message  ${test.kws[0].msgs[3]}  Repeated 3 times
+    Equals  ${test.kws[1].name}  2x BuiltIn.Log
+    Check Log Message  ${test.kws[1].msgs[1]}  Repeated 2 times
+    Check Log Message  ${test.kws[1].msgs[2]}  Repeated 2 times
+    Equals  ${test.kws[2].name}  0x BuiltIn.Fail
+
+Repeat With Valid String Variable
+    ${test} =  Check Test Case  Repeat With Valid String Variable
+    Equals  ${test.kws[1].name}  4x BuiltIn.Log
+    Check Log Message  ${test.kws[1].msgs[1]}  Repeated 4 times
+    Check Log Message  ${test.kws[1].msgs[2]}  Repeated 4 times
+    Check Log Message  ${test.kws[1].msgs[3]}  Repeated 4 times
+    Check Log Message  ${test.kws[1].msgs[4]}  Repeated 4 times
+
+Repeat With Variable Using Different Values
+ Check Test Case Repeat With Variable Using Different Values In One test + Check Test Case Repeat With Variable Using Different Values In Another test
+
+Repeat With Invalid String Variable
+    Check Test Case  ${TEST_NAME}
+
+No Repeat With Variable value 2x
+    Check Test Case  No Repeat With Variable Value 2x
+
+Repeat With Non Existing Variable Fails
+    ${test} =  Check Test Case  Repeat With Non Existing Variable Fails
+ Check Log Message ${test.kws[0].messages[1]} Non-existing variable '\${foo}'. FAIL
+
+Non Existing Keyword In Repeat With Variable
+    Check Test Case  Non Existing Keyword In Repeat With Variable
+
+Normal Keyword With X At The End
+    Check Test Case  Normal Keyword With X At The End
+
+*** Keywords ***
+Test Repeating Inside UK
+    [Arguments]  ${kw}
+    Check Log Message  ${kw.kws[0].msgs[0]}  Hello from Repeating UK
+    Check Log Message  ${kw.kws[1].msgs[0]}  Inside UK
+    Check Log Message  ${kw.kws[2].msgs[0]}  Hello from Repeating UK
+    Check Log Message  ${kw.kws[3].msgs[0]}  Inside UK
+    Check Log Message  ${kw.kws[4].msgs[0]}  Hello from Repeating UK
+    Check Log Message  ${kw.kws[5].msgs[0]}  Inside UK
+
+Verify Deprecation Messages
+    [Arguments]  ${msg}  ${x times}
+ ${exp} = Catenate Keyword '${ x times}' is deprecated. Replace X times syntax with 'Repeat Keyword'.
+    Check Log Message  ${msg}  ${exp}  WARN
+    Check Syslog Contains  | WARN \ |  ${exp}
+
=======================================
--- /dev/null
+++ /trunk/atest/testdata/keywords/repeating_keyword.txt Thu Dec 9 06:33:36 2010
@@ -0,0 +1,132 @@
+*** Variables ***
+${limit}  ${10}
+
+*** Test Cases ***
+Repeat Doing Nothing
+    1 x  No Operation
+    1000x  NOOPERATION
+
+Repeat With Arguments Doing Nothing
+    1 x  Comment  Nothing is done
+    42 X  Comment  Still  nothing
+
+Repeat With Messages
+    1 x  Log  Hello, world
+    33 x  Log  Hi, tellus
+
+Repeating User Keyword
+    1 x  Repeating UK  Yo, world
+    2 x  Repeating UK  Yo, tellus
+    2 x  Repeating UK With Sub KW
+
+Repeating Inside User Keyword
+    Repeating Inside UK
+
+Repeating Inside Repeating
+    4 x  Repeating Inside UK
+
+Failing Repeat Keyword
+    [Documentation]  FAIL Failing instead of repeating
+    42 x  Fail  Failing instead of repeating
+
+Not First Repeat Keyword Failing
+    [Documentation]  FAIL Recursion limit exceeded
+    1000x  Recursive
+
+Failing Repeat Keyword and Teardown
+ [Documentation] FAIL Failing, again, instead of repeating\n\nAlso teardown failed:\nTeardown is executed but fails
+    100 x  Fail  Failing, again, instead of repeating
+    [Teardown]  Fail  Teardown is executed but fails
+
+Non-Exising Variable In Repeat Keyword
+    [Documentation]  FAIL Non-existing variable '\${non-exiting-variable}'
+    1000x  Log  ${non-exiting-variable}
+
+Non Existing Keyword In Repeat
+ [Documentation] FAIL No keyword with name 'Non Existing Keyword' found.
+    1000x  Non Existing Keyword
+
+Zero Repeat
+    [Documentation]  This keyword is not executed
+    0 x  Fail  This should not be executed
+
+Negative Repeat
+    [Documentation]  Negative repeat is the same as zero repeat
+    -1 x  Fail  This should not be executed
+    -1111 x  Fail  This should not be executed
+
+Repeat With Valid Int Variable
+    ${3} x  Log  Repeated ${3} times
+    ${2}X  Log  Repeated ${2} times
+    ${0} X  Fail  This should not be executed!!
+    ${-100}x  Fail  This should not be executed!!
+
+Repeat With Valid String Variable
+    ${foo}  Set  4
+    ${foo} x  Log  Repeated ${foo} times
+
+Repeat With Variable Using Different Values In One test
+    Repeat With Variables  1
+    Repeat With Variables  2
+
+Repeat With Variable Using Different Values In Another test
+    Repeat With Variables  3
+
+Repeat With Invalid String Variable
+ [Documentation] FAIL 'bar' cannot be converted to an integer: ValueError: invalid literal for int() with base 10: 'bar'
+    ${foo} =  Set  bar
+    ${foo} x  Noop
+
+No Repeat With Variable value 2x
+    ${foo} =  Set  2 x
+    ${foo} =  Returning UK
+    Equals  ${foo}  String
+
+Repeat With Non Existing Variable Fails
+    [Documentation]  FAIL Non-existing variable '\${foo}'.
+    ${foo} x  Noop
+
+Non Existing Keyword In Repeat With Variable
+ [Documentation] FAIL No keyword with name 'Non Existing Keyword' found.
+    ${10} x  Non Existing Keyword
+
+Normal Keyword With X At The End
+    [Documentation]  FAIL No keyword with name 'Non Existing With X' found.
+    Keyword With X
+    Non Existing With X
+
+*** Keywords ***
+Repeating UK
+    [Arguments]  ${msg}
+    Log  Hello from Repeating UK
+    Log  ${msg}
+
+Repeating UK With Sub KW
+    Repeating UK  Sub kw
+
+Repeating Inside UK
+    3 x  Repeating UK  Inside UK
+
+Recursive
+    ${limit}  Evaluate  ${limit} - 1
+    Set Suite Variable  $limit
+    Fail If Ints Equal  ${limit}  0  Recursion limit exceeded  No values
+
+Returning UK
+    Noop
+    [Return]  String
+
+Keyword With X
+    NOOP
+
+Repeat With Variables
+    [Arguments]  ${count}
+    Log  ${count}
+    ${actually_repeated}  Set  0
+    ${count} X  Increase Count
+    Ints Equal  ${count}  ${actually_repeated}
+
+Increase Count
+    ${actually_repeated}  Evaluate  ${actually_repeated} + 1
+    Set Test Variable  $actually_repeated  ${actually_repeated}
+
=======================================
--- /trunk/src/robot/running/handlers.py        Thu Sep 16 00:17:34 2010
+++ /trunk/src/robot/running/handlers.py        Thu Dec  9 06:33:36 2010
@@ -258,6 +258,22 @@
         except DataError:
             return True

+class _XTimesHandler(_RunKeywordHandler):
+
+    def __init__(self, handler, name):
+        _RunKeywordHandler.__init__(self, handler.library, handler.name,
+                                    handler._handler_method)
+        self.name = name
+ self.doc = "*DEPRECATED* Replace X times syntax with 'Repeat Keyword'."
+
+    def run(self, context, args):
+ resolved_times = context.namespace.variables.replace_string(self.name)
+        _RunnableHandler.run(self, context, [resolved_times] + args)
+
+    @property
+    def longname(self):
+        return self.name
+

 class _DynamicRunKeywordHandler(_DynamicHandler, _RunKeywordHandler):
     _parse_arguments = _RunKeywordHandler._parse_arguments
=======================================
--- /trunk/src/robot/running/namespace.py       Fri Dec  3 01:42:43 2010
+++ /trunk/src/robot/running/namespace.py       Thu Dec  9 06:33:36 2010
@@ -18,7 +18,7 @@

 from robot import utils
 from robot.errors import FrameworkError, DataError
-from robot.variables import GLOBAL_VARIABLES
+from robot.variables import GLOBAL_VARIABLES, is_scalar_var
 from robot.common import UserErrorHandler
 from robot.output import LOGGER
 from robot.parsing.settings import Library, Variables, Resource
@@ -27,6 +27,7 @@
 from userkeyword import UserLibrary
 from importer import Importer
 from runkwregister import RUN_KW_REGISTER
+from handlers import _XTimesHandler


STDLIB_NAMES = ['BuiltIn', 'Collections', 'Dialogs', 'Easter', 'OperatingSystem',
@@ -258,8 +259,28 @@
             handler = self._get_implicit_handler(name)
         if not handler:
             handler = self._get_bdd_style_handler(name)
+        if not handler:
+            handler = self._get_x_times_handler(name)
         return handler

+    def _get_x_times_handler(self, name):
+        if not self._is_old_x_times_syntax(name):
+            return None
+        return _XTimesHandler(self._get_handler('Repeat Keyword'), name)
+
+    def _is_old_x_times_syntax(self, name):
+        if not name.lower().endswith('x'):
+            return False
+        times = name[:-1].strip()
+        if is_scalar_var(times):
+            return True
+        try:
+            int(times)
+        except ValueError:
+            return False
+        else:
+            return True
+
     def _get_bdd_style_handler(self, name):
         for prefix in ['given ', 'when ', 'then ', 'and ']:
             if name.lower().startswith(prefix):

Reply via email to