Skip to content

Commit d64f3c2

Browse files
committed
Fix listeners running kws inside FOR loop
Fixes #4112. Added tests also for listeners with IF/ELSE. Listeners aren't called with the root of the IF/ELSE structures so there were no problems. Listeners are called also with unexecuted IF/ELSE branches. That's perhaps a bit strange but I consider it a feature rather than a bug. Listeners can check the type of the executed "keyword" if needed.
1 parent 532aed8 commit d64f3c2

File tree

5 files changed

+53
-8
lines changed

5 files changed

+53
-8
lines changed

atest/resources/TestCheckerLibrary.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class NoSlotsForIteration(ForIteration):
4444

4545
class NoSlotsForIterations(ForIterations):
4646
for_iteration_class = NoSlotsForIteration
47+
keyword_class = NoSlotsKeyword
4748

4849

4950
NoSlotsKeyword.body_class = NoSlotsBody

atest/robot/output/listener_interface/using_run_keyword.robot

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,53 @@ In start_keyword and end_keyword with user keyword
7474
Check Log Message ${tc.body[3].body[2].body[0]} end_keyword
7575
Length Should Be ${tc.body[3].body} 3
7676

77+
In start_keyword and end_keyword with FOR loop
78+
${tc} = Check Test Case FOR loop in test
79+
${for} = Set Variable ${tc.body[1]}
80+
Should Be Equal ${for.type} FOR
81+
Length Should Be ${for.body} 5
82+
Length Should Be ${for.body.filter(keywords=True)} 2
83+
Should Be Equal ${for.body[0].name} BuiltIn.Log
84+
Check Log Message ${for.body[0].body[0]} start_keyword
85+
Should Be Equal ${for.body[-1].name} BuiltIn.Log
86+
Check Log Message ${for.body[-1].body[0]} end_keyword
87+
88+
In start_keyword and end_keyword with IF/ELSE
89+
${tc} = Check Test Case IF structure
90+
Should Be Equal ${tc.body[1].type} IF/ELSE ROOT
91+
Length Should Be ${tc.body[1].body} 3 # Listener if not called with root
92+
Validate IF branch ${tc.body[1].body[0]} IF NOT RUN # but is called with unexecuted branches.
93+
Validate IF branch ${tc.body[1].body[1]} ELSE IF PASS
94+
Validate IF branch ${tc.body[1].body[2]} ELSE NOT RUN
95+
7796
*** Keywords ***
7897
Run Tests With Keyword Running Listener
7998
${path} = Normalize Path ${LISTENER DIR}/keyword_running_listener.py
80-
Run Tests --listener ${path} misc/normal.robot misc/setups_and_teardowns.robot
99+
${files} = Catenate
100+
... misc/normal.robot
101+
... misc/setups_and_teardowns.robot
102+
... misc/for_loops.robot
103+
... misc/if_else.robot
104+
Run Tests --listener ${path} ${files}
81105
Should Be Empty ${ERRORS}
106+
107+
Validate IF branch
108+
[Arguments] ${branch} ${type} ${status}
109+
Should Be Equal ${branch.type} ${type}
110+
Should Be Equal ${branch.status} ${status}
111+
Length Should Be ${branch.body} 3
112+
Should Be Equal ${branch.body[0].name} BuiltIn.Log
113+
Check Log Message ${branch.body[0].body[0]} start_keyword
114+
IF $status == 'PASS'
115+
Should Be Equal ${branch.body[1].name} BuiltIn.Log
116+
Should Be Equal ${branch.body[1].body[0].name} BuiltIn.Log
117+
Check Log Message ${branch.body[1].body[0].body[0]} start_keyword
118+
Check Log Message ${branch.body[1].body[1]} else if branch
119+
Should Be Equal ${branch.body[1].body[2].name} BuiltIn.Log
120+
Check Log Message ${branch.body[1].body[2].body[0]} end_keyword
121+
ELSE
122+
Should Be Equal ${branch.body[1].name} BuiltIn.Fail
123+
Should Be Equal ${branch.body[1].status} NOT RUN
124+
END
125+
Should Be Equal ${branch.body[-1].name} BuiltIn.Log
126+
Check Log Message ${branch.body[-1].body[0]} end_keyword

src/robot/result/model.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ def filter(self, keywords=None, fors=None, ifs=None, messages=None, predicate=No
6363

6464
class ForIterations(Body):
6565
for_iteration_class = None
66-
keyword_class = None
6766
if_class = None
6867
for_class = None
6968
__slots__ = []

src/robot/result/xmlelementhandlers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def _create_foritem(self, elem, result):
168168
@ElementHandler.register
169169
class ForHandler(ElementHandler):
170170
tag = 'for'
171-
children = frozenset(('var', 'value', 'doc', 'status', 'iter', 'msg'))
171+
children = frozenset(('var', 'value', 'doc', 'status', 'iter', 'msg', 'kw'))
172172

173173
def start(self, elem, result):
174174
return result.body.create_for(flavor=elem.get('flavor'))

utest/result/test_resultmodel.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -336,18 +336,18 @@ def test_id(self):
336336

337337
class TestForIterations(unittest.TestCase):
338338

339-
def test_create_iteration_message_supported(self):
339+
def test_create_supported(self):
340340
for_ = For()
341341
iterations = for_.body
342342
for creator in (iterations.create_iteration,
343-
iterations.create_message):
343+
iterations.create_message,
344+
iterations.create_keyword):
344345
item = creator()
345346
assert_equal(item.parent, for_)
346347

347-
def test_create_keyword_for_if_not_supported(self):
348+
def test_create_not_supported(self):
348349
iterations = For().body
349-
for creator in (iterations.create_keyword,
350-
iterations.create_for,
350+
for creator in (iterations.create_for,
351351
iterations.create_if):
352352
msg = "'ForIterations' object does not support '%s'." % creator.__name__
353353
assert_raises_with_msg(TypeError, msg, creator)

0 commit comments

Comments
 (0)