Skip to content

Commit

Permalink
Recommend $x syntax if invalid IF or WHILE has ${x}
Browse files Browse the repository at this point in the history
For example, `${var} == 'value'` fails for NameError if `${var}` is a
string and using `$var == 'value'` avoids that. Fixes #4676.
  • Loading branch information
pekkaklarck committed Mar 10, 2023
1 parent 0622147 commit 27a533e
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 91 deletions.
17 changes: 12 additions & 5 deletions atest/robot/running/if/invalid_if.robot
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@ IF with invalid condition
IF with invalid condition with ELSE
FAIL NOT RUN

IF condition with non-existing variable
IF condition with non-existing ${variable}
FAIL NOT RUN

IF condition with non-existing $variable
FAIL NOT RUN

ELSE IF with invalid condition
NOT RUN NOT RUN FAIL NOT RUN NOT RUN

Recommend $var syntax if invalid condition contains ${var}
FAIL index=1

IF without END
FAIL

Expand Down Expand Up @@ -106,11 +112,12 @@ Non-existing variable in condition causes normal error

*** Keywords ***
Branch statuses should be
[Arguments] @{statuses}
[Arguments] @{statuses} ${index}=0
${tc} = Check Test Case ${TESTNAME}
Should Be Equal ${tc.body[0].status} FAIL
FOR ${branch} ${status} IN ZIP ${tc.body[0].body} ${statuses}
${if} = Set Variable ${tc.body}[${index}]
Should Be Equal ${if.status} FAIL
FOR ${branch} ${status} IN ZIP ${if.body} ${statuses}
Should Be Equal ${branch.status} ${status}
END
Should Be Equal ${{len($tc.body[0].body)}} ${{len($statuses)}}
Should Be Equal ${{len($if.body)}} ${{len($statuses)}}
RETURN ${tc}
7 changes: 6 additions & 1 deletion atest/robot/running/if/invalid_inline_if.robot
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ Assign when ELSE IF branch is empty
Assign when ELSE branch is empty
FAIL NOT RUN

Assign with RETURN
Control structures are allowed
[Template] NONE
${tc} = Check Test Case ${TESTNAME}
Check IF/ELSE Status NOT RUN PASS root=${tc.body[0].body[0]}

Control structures are not allowed with assignment
[Template] NONE
${tc} = Check Test Case ${TESTNAME}
Check IF/ELSE Status FAIL NOT RUN root=${tc.body[0].body[0]}
12 changes: 9 additions & 3 deletions atest/robot/running/while/invalid_while.robot
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ Multiple conditions
Invalid condition
Check Invalid WHILE Test Case

Invalid condition on second round
Check Test Case ${TEST NAME}
Non-existing ${variable} in condition
Check Invalid WHILE Test Case

Non-existing variable in condition
Non-existing $variable in condition
Check Invalid WHILE Test Case

Recommend $var syntax if invalid condition contains ${var}
Check Test Case ${TEST NAME}

Invalid condition on second round
Check Test Case ${TEST NAME}

No body
Check Invalid WHILE Test Case body=False

Expand Down
41 changes: 31 additions & 10 deletions atest/testdata/running/if/invalid_if.robot
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,38 @@ IF without condition with ELSE
END

IF with invalid condition
[Documentation] FAIL STARTS: Evaluating IF condition failed: Evaluating expression ''123'=123' failed: SyntaxError:
[Documentation] FAIL STARTS: Invalid IF condition: Evaluating expression ''123'=123' failed: SyntaxError:
IF '123'=${123}
Fail Should not be run
END

IF condition with non-existing variable
[Documentation] FAIL Evaluating IF condition failed: Variable '\${ooop}' not found.
IF condition with non-existing ${variable}
[Documentation] FAIL Invalid IF condition: Evaluating expression '\${ooop}' failed: Variable '\${ooop}' not found.
IF ${ooop}
Fail Should not be run
ELSE IF ${not evaluated}
Not run
END

IF condition with non-existing $variable
[Documentation] FAIL Invalid IF condition: Evaluating expression '$ooop' failed: Variable '$ooop' not found.
IF $ooop
Fail Should not be run
ELSE IF $not_evaluated
Not run
END

IF with invalid condition with ELSE
[Documentation] FAIL Evaluating IF condition failed: Evaluating expression 'ooops' failed: NameError: name 'ooops' is not defined nor importable as module
[Documentation] FAIL Invalid IF condition: \
... Evaluating expression 'ooops' failed: NameError: name 'ooops' is not defined nor importable as module
IF ooops
Fail Should not be run
ELSE
Fail Should not be run
END

ELSE IF with invalid condition
[Documentation] FAIL STARTS: Evaluating ELSE IF condition failed: Evaluating expression '1/0' failed: ZeroDivisionError:
[Documentation] FAIL STARTS: Invalid ELSE IF condition: Evaluating expression '1/0' failed: ZeroDivisionError:
IF False
Fail Should not be run
ELSE IF False
Expand All @@ -49,6 +58,18 @@ ELSE IF with invalid condition
Fail Should not be run
END

Recommend $var syntax if invalid condition contains ${var}
[Documentation] FAIL Invalid IF condition: \
... Evaluating expression 'x == 'x'' failed: NameError: name 'x' is not defined nor importable as module
...
... Variables in the original expression '\${x} == 'x'' were resolved before the expression was evaluated. \
... Try using '$x == 'x'' syntax to avoid that. See Evaluating Expressions appendix in Robot Framework User Guide for more details.
${x} = Set Variable x
IF ${x} == 'x'
Fail Shouldn't be run
END


IF without END
[Documentation] FAIL IF must have closing END.
IF ${True}
Expand Down Expand Up @@ -221,14 +242,14 @@ Invalid condition causes normal error
[Documentation] FAIL Teardown failed:
... Several failures occurred:
...
... 1) Evaluating IF condition failed: Evaluating expression 'bad in teardown' failed: NameError: name 'bad' is not defined nor importable as module
... 1) Invalid IF condition: Evaluating expression 'bad in teardown' failed: NameError: name 'bad' is not defined nor importable as module
...
... 2) Should be run in teardown
TRY
IF bad
Fail Should not be run
END
EXCEPT Evaluating IF condition failed: Evaluating expression 'bad' failed: NameError: name 'bad' is not defined nor importable as module
EXCEPT Invalid IF condition: Evaluating expression 'bad' failed: NameError: name 'bad' is not defined nor importable as module
No Operation
END
[Teardown] Invalid condition
Expand All @@ -237,14 +258,14 @@ Non-existing variable in condition causes normal error
[Documentation] FAIL Teardown failed:
... Several failures occurred:
...
... 1) Evaluating IF condition failed: Variable '\${bad}' not found.
... 1) Invalid IF condition: Evaluating expression '\${oops}' failed: Variable '\${oops}' not found.
...
... 2) Should be run in teardown
TRY
IF ${bad}
Fail Should not be run
END
EXCEPT Evaluating IF condition failed: Variable '\${bad}' not found.
EXCEPT Invalid IF condition: Evaluating expression '\${bad}' failed: Variable '\${bad}' not found.
No Operation
END
[Teardown] Non-existing variable in condition
Expand All @@ -259,7 +280,7 @@ Invalid condition
Fail Should be run in teardown

Non-existing variable in condition
IF ${bad}
IF ${oops}
Fail Should not be run
END
Fail Should be run in teardown
88 changes: 51 additions & 37 deletions atest/testdata/running/if/invalid_inline_if.robot
Original file line number Diff line number Diff line change
@@ -1,160 +1,174 @@
*** Test Cases ***
Invalid condition
[Documentation] FAIL Evaluating IF condition failed: Evaluating expression 'ooops' failed: NameError: name 'ooops' is not defined nor importable as module
[Documentation] FAIL Invalid IF condition: \
... Evaluating expression 'ooops' failed: NameError: name 'ooops' is not defined nor importable as module
IF ooops Not run ELSE Not run either

Condition with non-existing variable
[Documentation] FAIL Evaluating IF condition failed: Variable '\${ooops}' not found.
[Documentation] FAIL Invalid IF condition: \
... Evaluating expression '${ooops}' failed: Variable '\${ooops}' not found.
IF ${ooops} Not run

Invalid condition with other error
[Documentation] FAIL ELSE branch cannot be empty.
[Documentation] FAIL ELSE branch cannot be empty.
IF bad Not run ELSE

Empty IF
[Documentation] FAIL Multiple errors:
[Documentation] FAIL
... Multiple errors:
... - IF must have a condition.
... - IF branch cannot be empty.
... - IF must have closing END.
IF

IF without branch
[Documentation] FAIL Multiple errors:
[Documentation] FAIL
... Multiple errors:
... - IF branch cannot be empty.
... - IF must have closing END.
IF True

IF without branch with ELSE IF
[Documentation] FAIL IF branch cannot be empty.
[Documentation] FAIL IF branch cannot be empty.
IF True ELSE IF True Not run

IF without branch with ELSE
[Documentation] FAIL IF branch cannot be empty.
[Documentation] FAIL IF branch cannot be empty.
IF True ELSE Not run

IF followed by ELSE IF
[Documentation] FAIL STARTS: Evaluating IF condition failed: Evaluating expression 'ELSE IF' failed:
[Documentation] FAIL STARTS: Invalid IF condition: Evaluating expression 'ELSE IF' failed:
IF ELSE IF False Not run

IF followed by ELSE
[Documentation] FAIL Evaluating IF condition failed: Evaluating expression 'ELSE' failed: NameError: name 'ELSE' is not defined nor importable as module
[Documentation] FAIL Invalid IF condition: \
... Evaluating expression 'ELSE' failed: NameError: name 'ELSE' is not defined nor importable as module
IF ELSE Not run

Empty ELSE IF 1
[Documentation] FAIL Multiple errors:
[Documentation] FAIL
... Multiple errors:
... - ELSE IF must have a condition.
... - ELSE IF branch cannot be empty.
IF False Not run ELSE IF

Empty ELSE IF 2
[Documentation] FAIL Evaluating ELSE IF condition failed: Evaluating expression 'ELSE' failed: NameError: name 'ELSE' is not defined nor importable as module
[Documentation] FAIL Invalid ELSE IF condition: \
... Evaluating expression 'ELSE' failed: NameError: name 'ELSE' is not defined nor importable as module
IF False Not run ELSE IF ELSE Not run

ELSE IF without branch 1
[Documentation] FAIL ELSE IF branch cannot be empty.
[Documentation] FAIL ELSE IF branch cannot be empty.
IF False Not run ELSE IF False

ELSE IF without branch 2
[Documentation] FAIL ELSE IF branch cannot be empty.
[Documentation] FAIL ELSE IF branch cannot be empty.
IF False Not run ELSE IF False ELSE Not run

Empty ELSE
[Documentation] FAIL ELSE branch cannot be empty.
[Documentation] FAIL ELSE branch cannot be empty.
IF True Not run ELSE IF True Not run ELSE

ELSE IF after ELSE 1
[Documentation] FAIL ELSE IF not allowed after ELSE.
[Documentation] FAIL ELSE IF not allowed after ELSE.
IF True Not run ELSE Not run ELSE IF True Not run

ELSE IF after ELSE 2
[Documentation] FAIL ELSE IF not allowed after ELSE.
[Documentation] FAIL ELSE IF not allowed after ELSE.
IF True Not run ELSE Not run ELSE IF True Not run ELSE IF True Not run

Multiple ELSEs 1
[Documentation] FAIL Only one ELSE allowed.
[Documentation] FAIL Only one ELSE allowed.
IF True Not run ELSE Not run ELSE Not run

Multiple ELSEs 2
[Documentation] FAIL Only one ELSE allowed.
[Documentation] FAIL Only one ELSE allowed.
IF True Not run ELSE Not run ELSE Not run ELSE Not run

Nested IF 1
[Documentation] FAIL Inline IF cannot be nested.
[Documentation] FAIL Inline IF cannot be nested.
IF True IF True Not run

Nested IF 2
[Documentation] FAIL Inline IF cannot be nested.
[Documentation] FAIL Inline IF cannot be nested.
IF True Not run ELSE IF True Not run

Nested IF 3
[Documentation] FAIL Inline IF cannot be nested.
[Documentation] FAIL Inline IF cannot be nested.
IF True IF True Not run
... ELSE IF True IF True Not run
... ELSE IF True Not run

Nested FOR
[Documentation] FAIL 'For' is a reserved keyword. It must be an upper case 'FOR' when used as a marker.
[Documentation] FAIL 'For' is a reserved keyword. It must be an upper case 'FOR' when used as a marker.
IF True FOR ${x} IN @{stuff}

Unnecessary END
[Documentation] FAIL Keyword 'BuiltIn.No Operation' expected 0 arguments, got 1.
[Documentation] FAIL Keyword 'BuiltIn.No Operation' expected 0 arguments, got 1.
IF True No operation ELSE Log END
IF False Not run ELSE No operation END

Invalid END after inline header
[Documentation] FAIL END is not allowed in this context.
[Documentation] FAIL END is not allowed in this context.
IF True Log Executed inside inline IF
Log Executed outside IF
END

Assign in IF branch
[Documentation] FAIL Inline IF branches cannot contain assignments.
[Documentation] FAIL Inline IF branches cannot contain assignments.
IF False ${x} = Whatever

Assign in ELSE IF branch
[Documentation] FAIL Inline IF branches cannot contain assignments.
[Documentation] FAIL Inline IF branches cannot contain assignments.
IF False Keyword ELSE IF False ${x} = Whatever

Assign in ELSE branch
[Documentation] FAIL Inline IF branches cannot contain assignments.
[Documentation] FAIL Inline IF branches cannot contain assignments.
IF False Keyword ELSE ${x} = Whatever

Invalid assign mark usage
[Documentation] FAIL Assign mark '=' can be used only with the last variable.
[Documentation] FAIL Assign mark '=' can be used only with the last variable.
${x} = ${y} IF True Create list x y

Too many list variables in assign
[Documentation] FAIL Assignment can contain only one list variable.
[Documentation] FAIL Assignment can contain only one list variable.
@{x} @{y} = IF True Create list x y ELSE Not run

Invalid number of variables in assign
[Documentation] FAIL Cannot set variables: Expected 2 return values, got 3.
[Documentation] FAIL Cannot set variables: Expected 2 return values, got 3.
${x} ${y} = IF False Create list x y ELSE Create list x y z

Invalid value for list assign
[Documentation] FAIL Cannot set variable '\@{x}': Expected list-like value, got string.
[Documentation] FAIL Cannot set variable '\@{x}': Expected list-like value, got string.
@{x} = IF True Set variable String is not list

Invalid value for dict assign
[Documentation] FAIL Cannot set variable '\&{x}': Expected dictionary-like value, got string.
[Documentation] FAIL Cannot set variable '\&{x}': Expected dictionary-like value, got string.
&{x} = IF False Not run ELSE Set variable String is not dict either

Assign when IF branch is empty
[Documentation] FAIL IF branch cannot be empty.
[Documentation] FAIL IF branch cannot be empty.
${x} = IF False

Assign when ELSE IF branch is empty
[Documentation] FAIL ELSE IF branch cannot be empty.
[Documentation] FAIL ELSE IF branch cannot be empty.
${x} = IF True Not run ELSE IF True

Assign when ELSE branch is empty
[Documentation] FAIL ELSE branch cannot be empty.
[Documentation] FAIL ELSE branch cannot be empty.
${x} = IF True Not run ELSE

Assign with RETURN
[Documentation] FAIL Inline IF with assignment can only contain keyword calls.
Control structures are allowed
With RETURN

Control structures are not allowed with assignment
[Documentation] FAIL Inline IF with assignment can only contain keyword calls.
Assign with RETURN

*** Keywords ***
With RETURN
IF False Fail Not run ELSE RETURN
Fail Not run

Assign with RETURN
${x} = IF False RETURN ELSE Not run

0 comments on commit 27a533e

Please sign in to comment.