Skip to content

Commit

Permalink
Pass embedded args as objects to Run Keyword and its variants.
Browse files Browse the repository at this point in the history
Earlier variables were replaced in keyword names before keywords were
called. This meant that keywords using embedded arguments only go
string representations of objects, not objects themselves.

The biggest change that the `name` argument passed to
`BuiltIn.run_keyword` isn't anymore resolved before calling the
keyword. Instead the keyword resolves it itself after first checking
does it match some keyword accepting embedded arguments. If it does,
`name` is not resolved and variables will be handled later by
appropriate runners.

The above change ought to be backwards compatible when using `Run
Keyword` in data, but if `BuiltIn.run_keyword` is used by a library
keyword handling of the `name` argument changes. This only affects
situations where the name contains variables or escapes so it
shouldn't cause problems in normal usage.

Not resolving `name` caused various bigger and smaller changes
elsewhere. For example, how run keyword variants were handled in dry
run was affected and that logic needed to be changed. The bad and
deprecated RUN_KW_REGISTER was enhanced to help with that and
its documentation was enhanced at the same time.

Fixes #1595.
  • Loading branch information
pekkaklarck committed Sep 10, 2022
1 parent f75c5b2 commit 8301773
Show file tree
Hide file tree
Showing 17 changed files with 429 additions and 167 deletions.
2 changes: 1 addition & 1 deletion atest/robot/keywords/trace_log_keyword_arguments.robot
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Object With Unicode Repr as Argument

Arguments With Run Keyword
${tc}= Check Test Case ${TEST NAME}
Check Log Message ${tc.kws[1].msgs[0]} Arguments: [ 'Catenate' | '\@{VALUES}' ] TRACE
Check Log Message ${tc.kws[1].msgs[0]} Arguments: [ '\${keyword name}' | '\@{VALUES}' ] TRACE
Check Log Message ${tc.kws[1].kws[0].msgs[0]} Arguments: [ 'a' | 'b' | 'c' | 'd' ] TRACE

Embedded Arguments
Expand Down
15 changes: 9 additions & 6 deletions atest/robot/standard_libraries/builtin/repeat_keyword.robot
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ Times With 'x' Postfix

Zero And Negative Times
${tc} = Check Test Case ${TEST NAME}
Check Repeated Messages ${tc.kws[0]} 0
Check Repeated Messages ${tc.kws[2]} 0
Check Repeated Messages ${tc.kws[3]} 0
Check Repeated Messages ${tc.kws[0]} 0 name=This is not executed
Check Repeated Messages ${tc.kws[2]} 0 name=\${name}
Check Repeated Messages ${tc.kws[3]} 0 name=This is not executed

Invalid Times
Check Test Case Invalid Times 1
Expand Down Expand Up @@ -72,14 +72,17 @@ Repeat Keyword With Pass Execution After Continuable Failure

*** Keywords ***
Check Repeated Messages
[Arguments] ${kw} ${count} ${msg}=${None}
[Arguments] ${kw} ${count} ${msg}= ${name}=
Should Be Equal As Integers ${kw.kw_count} ${count}
FOR ${i} IN RANGE ${count}
Check Log Message ${kw.msgs[${i}]} Repeating keyword, round ${i+1}/${count}.
Check Log Message ${kw.kws[${i}].msgs[0]} ${msg}
END
Run Keyword If ${count} == 0 Check Log Message ${kw.msgs[0]} Keyword 'This is not executed' repeated zero times.
Run Keyword If ${count} != 0 Should Be Equal As Integers ${kw.msg_count} ${count}
IF ${count} != 0
Should Be Equal As Integers ${kw.msg_count} ${count}
ELSE
Check Log Message ${kw.msgs[0]} Keyword '${name}' repeated zero times.
END

Check Repeated Messages With Time
[Arguments] ${kw} ${msg}=${None}
Expand Down
40 changes: 40 additions & 0 deletions atest/robot/standard_libraries/builtin/run_keyword.robot
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,34 @@ Run Keyword With UK
Run Keyword In Multiple Levels And With UK
Check test Case ${TEST NAME}

With keyword accepting embedded arguments
${tc} = Check test Case ${TEST NAME}
Check Run Keyword With Embedded Args ${tc.kws[0]} Embedded "arg" arg

With library keyword accepting embedded arguments
${tc} = Check test Case ${TEST NAME}
Check Run Keyword With Embedded Args ${tc.kws[0]} Embedded "arg" in library arg

With keyword accepting embedded arguments as variables
${tc} = Check test Case ${TEST NAME}
Check Run Keyword With Embedded Args ${tc.kws[0]} Embedded "\${VARIABLE}" value
Check Run Keyword With Embedded Args ${tc.kws[1]} Embedded "\${1}" 1

With library keyword accepting embedded arguments as variables
${tc} = Check test Case ${TEST NAME}
Check Run Keyword With Embedded Args ${tc.kws[0]} Embedded "\${VARIABLE}" in library value
Check Run Keyword With Embedded Args ${tc.kws[1]} Embedded "\${1}" in library 1

With keyword accepting embedded arguments as variables containing objects
${tc} = Check test Case ${TEST NAME}
Check Run Keyword With Embedded Args ${tc.kws[0]} Embedded "\${OBJECT}" Robot
Check Run Keyword With Embedded Args ${tc.kws[1]} Embedded object "\${OBJECT}" Robot

With library keyword accepting embedded arguments as variables containing objects
${tc} = Check test Case ${TEST NAME}
Check Run Keyword With Embedded Args ${tc.kws[0]} Embedded "\${OBJECT}" in library Robot
Check Run Keyword With Embedded Args ${tc.kws[1]} Embedded object "\${OBJECT}" in library Robot

Run Keyword In For Loop
${tc} = Check test Case ${TEST NAME}
Check Run Keyword ${tc.kws[0].kws[0].kws[0]} BuiltIn.Log hello from for loop
Expand Down Expand Up @@ -81,3 +109,15 @@ Check Run Keyword In Uk
Should Be Equal ${kw.name} BuiltIn.Run Keyword
Should Be Equal ${kw.kws[0].name} My UK
Check Run Keyword ${kw.kws[0].kws[0]} ${subkw_name} @{msgs}

Check Run Keyword With Embedded Args
[Arguments] ${kw} ${subkw_name} ${msg}
Should Be Equal ${kw.name} BuiltIn.Run Keyword
IF ${subkw_name.endswith('library')}
Should Be Equal ${kw.kws[0].name} embedded_args.${subkw_name}
Check Log Message ${kw.kws[0].msgs[0]} ${msg}
ELSE
Should Be Equal ${kw.kws[0].name} ${subkw_name}
Should Be Equal ${kw.kws[0].kws[0].name} BuiltIn.Log
Check Log Message ${kw.kws[0].kws[0].msgs[0]} ${msg}
END
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,25 @@ Resource atest_resource.robot
*** Test Case ***
Variable Values Should Not Be Visible As Keyword's Arguments
${tc} = Check Test Case ${TEST NAME}
Check Keyword Data ${tc.kws[0]} BuiltIn.Run Keyword args=My UK, Log, \${OBJECT}
Check Keyword Data ${tc.kws[0].kws[0]} My UK args=Log, \${OBJECT}
Check Keyword Data ${tc.kws[0].kws[0].kws[0]} BuiltIn.Run Keyword args=\${name}, \@{args}
Check Keyword Data ${tc.kws[0].kws[0].kws[0].kws[0]} BuiltIn.Log args=\@{args}
Check Keyword Data ${tc.kws[0]} BuiltIn.Run Keyword args=My UK, Log, \${OBJECT}
Check Keyword Data ${tc.kws[0].kws[0]} My UK args=Log, \${OBJECT}
Check Keyword Data ${tc.kws[0].kws[0].kws[0]} BuiltIn.Run Keyword args=\${name}, \@{args}
Check Keyword Data ${tc.kws[0].kws[0].kws[0].kws[0]} BuiltIn.Log args=\@{args}
Check Log Message ${tc.kws[0].kws[0].kws[0].kws[0].msgs[0]} Robot
Check Keyword Data ${tc.kws[0].kws[0].kws[1].kws[0]} BuiltIn.Log args=\${args}[0]
Check Log Message ${tc.kws[0].kws[0].kws[1].kws[0].msgs[0]} Robot

Run Keyword When Keyword and Arguments Are in List Variable
${tc} = Check Test Case ${TEST NAME}
Check Keyword Data ${tc.kws[0].kws[0]} \\Log Many args=c:\\\\temp\\\\foo, \\\${notvar}
Check Keyword Data ${tc.kws[1].kws[0]} \\Log Many args=\\\${notvar}

Run Keyword With Empty List Variable
Check Test Case ${TEST NAME}

Run Keyword With Multiple Empty List Variables
Check Test Case ${TEST NAME}

Run Keyword If When Arguments are In Multiple List
${tc} = Check Test Case ${TEST NAME}
Check Keyword Arguments And Messages ${tc}
Expand Down
36 changes: 30 additions & 6 deletions atest/robot/standard_libraries/builtin/run_keywords.robot
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
*** Settings ***
Documentation Testing Run Keywords when used without AND. Tests with AND are in
... run_keywords_with_arguments.robot.
Suite Setup Run Tests ${EMPTY} standard_libraries/builtin/run_keywords.robot
Resource atest_resource.robot

Expand All @@ -12,6 +14,26 @@ Failing keyword
Test Should Have Correct Keywords
... Passing Failing

Embedded arguments
${tc} = Test Should Have Correct Keywords
... Embedded "arg" Embedded "\${1}" Embedded object "\${OBJECT}"
Check Log Message ${tc.kws[0].kws[0].kws[0].msgs[0]} arg
Check Log Message ${tc.kws[0].kws[1].kws[0].msgs[0]} 1
Check Log Message ${tc.kws[0].kws[2].kws[0].msgs[0]} Robot

Embedded arguments with library keywords
${tc} = Test Should Have Correct Keywords
... embedded_args.Embedded "arg" in library
... embedded_args.Embedded "\${1}" in library
... embedded_args.Embedded object "\${OBJECT}" in library
Check Log Message ${tc.kws[0].kws[0].msgs[0]} arg
Check Log Message ${tc.kws[0].kws[1].msgs[0]} 1
Check Log Message ${tc.kws[0].kws[2].msgs[0]} Robot

Keywords names needing escaping
Test Should Have Correct Keywords
... Needs \\escaping \\\${notvar}

Continuable failures
Test Should Have Correct Keywords
... Continuable failure Multiple continuables Failing
Expand All @@ -21,9 +43,14 @@ Keywords as variables
... BuiltIn.No Operation Passing BuiltIn.No Operation
... Passing BuiltIn.Log Variables Failing

Keywords names needing escaping as variable
Test Should Have Correct Keywords
... Needs \\escaping \\\${notvar} Needs \\escaping \\\${notvar}
... kw_index=1

Non-existing variable as keyword name
${tc} = Check Test Case ${TESTNAME}
Should Be Empty ${tc.kws[0].kws}
Test Should Have Correct Keywords
... Passing

Non-existing variable inside executed keyword
Test Should Have Correct Keywords
Expand All @@ -43,10 +70,7 @@ In test setup
In test teardown
Check Test Case ${TESTNAME}

In test teardown with non-existing variable in keyword name (with AND)
Check Test Case ${TESTNAME}

In test teardown with non-existing variable in keyword name (without AND)
In test teardown with non-existing variable in keyword name
Check Test Case ${TESTNAME}

In test teardown with ExecutionPassed exception
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
*** Settings ***
Documentation Testing Run Keywords when used with AND. Tests without AND are in
... run_keywords.robot.
Suite Setup Run Tests ${EMPTY} standard_libraries/builtin/run_keywords_with_arguments.robot
Resource atest_resource.robot

Expand Down Expand Up @@ -54,3 +56,15 @@ Consecutive AND's

AND as first argument should raise an error
Check Test Case ${TESTNAME}

Keywords names needing escaping
Test Should Have Correct Keywords
... Needs \\escaping \\\${notvar} Needs \\escaping \\\${notvar}

Keywords names needing escaping as variable
Test Should Have Correct Keywords
... Needs \\escaping \\\${notvar} Needs \\escaping \\\${notvar}
... kw_index=1

In test teardown with non-existing variable in keyword name
Check Test Case ${TESTNAME}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ def run_keyword_function(name, *args):
register_run_keyword(__name__, 'run_keyword_function', 1)

def run_keyword_without_keyword(*args):
return BuiltIn().run_keyword('\Log Many', *args)
return BuiltIn().run_keyword(r'\\Log Many', *args)

register_run_keyword(__name__, 'run_keyword_without_keyword', 0)
13 changes: 13 additions & 0 deletions atest/testdata/standard_libraries/builtin/embedded_args.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from robot.api.deco import keyword


@keyword('Embedded "${argument}" in library')
def embedded(arg):
print(arg)


@keyword('Embedded object "${obj}" in library')
def embedded_object(obj):
print(obj)
if obj.name != 'Robot':
raise AssertionError(f"'{obj.name}' != 'Robot'")
32 changes: 32 additions & 0 deletions atest/testdata/standard_libraries/builtin/run_keyword.robot
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
*** Settings ***
Library OperatingSystem
Library embedded_args.py
Variables variable.py

*** Variables ***
@{NEEDS ESCAPING} c:\\temp\\foo \${notvar} ${42}
${FAIL KW} Fail
${VARIABLE} value

*** Test Cases ***
Run Keyword
Expand Down Expand Up @@ -48,6 +51,28 @@ Run Keyword In Multiple Levels And With UK
Run Keyword Run Keyword Run Keyword My UK Run Keyword
... My UK My UK My UK Run Keyword Fail Expected Failure

With keyword accepting embedded arguments
Run Keyword Embedded "arg"

With library keyword accepting embedded arguments
Run Keyword Embedded "arg" in library

With keyword accepting embedded arguments as variables
Run Keyword Embedded "${VARIABLE}"
Run Keyword Embedded "${1}"

With library keyword accepting embedded arguments as variables
Run Keyword Embedded "${VARIABLE}" in library
Run Keyword Embedded "${1}" in library

With keyword accepting embedded arguments as variables containing objects
Run Keyword Embedded "${OBJECT}"
Run Keyword Embedded object "${OBJECT}"

With library keyword accepting embedded arguments as variables containing objects
Run Keyword Embedded "${OBJECT}" in library
Run Keyword Embedded object "${OBJECT}" in library

Run Keyword In For Loop
[Documentation] FAIL Expected failure in For Loop
FOR ${kw} ${arg1} ${arg2} IN
Expand Down Expand Up @@ -99,3 +124,10 @@ Timeoutted UK Passing
Timeoutted UK Timeouting
[Timeout] 300 milliseconds
Sleep 1 second

Embedded "${arg}"
Log ${arg}

Embedded object "${obj}"
Log ${obj}
Should Be Equal ${obj.name} Robot
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Variables variable.py
@{NEEDS ESCAPING} c:\\temp\\foo \${notvar}
@{KEYWORD AND ARG WHICH NEEDS ESCAPING} \\Log Many \${notvar}
@{KEYWORD AND ARGS WHICH NEEDS ESCAPING} \\Log Many @{NEEDS ESCAPING}
@{EMPTY}
@{EXPRESSION} ${TRUE}
@{ARGS} @{NEEDS ESCAPING}
${KEYWORD} \\Log Many
Expand All @@ -20,6 +19,16 @@ Run Keyword When Keyword and Arguments Are in List Variable
Run Keyword @{KEYWORD AND ARGS WHICH NEEDS ESCAPING}
Run Keyword @{KEYWORD AND ARG WHICH NEEDS ESCAPING}

Run Keyword With Empty List Variable
[Documentation] FAIL
... Keyword name missing: Given arguments ['\@{EMPTY}'] resolved to an empty list.
Run Keyword @{EMPTY}

Run Keyword With Multiple Empty List Variables
[Documentation] FAIL
... Keyword name missing: Given arguments ['\@{EMPTY}', '\@{{{}}}', '\@{EMPTY}'] resolved to an empty list.
Run Keyword @{EMPTY} @{{{}}} @{EMPTY}

Run Keyword If When Arguments are In Multiple List
Run Keyword If @{EXPRESSION} @{KEYWORD LIST} @{ARGS}

Expand Down Expand Up @@ -50,6 +59,8 @@ Run Keyword If With List And One Argument That needs to Be Processed
My UK
[Arguments] ${name} @{args}
Run Keyword ${name} @{args}
Run Keyword ${name} ${args}[0]
Should Be Equal ${args[0].name} Robot

\Log Many
[Arguments] @{args}
Expand Down

0 comments on commit 8301773

Please sign in to comment.