Skip to content

Commit 1f7bc54

Browse files
committed
fix line continuation corner cases
1 parent f01f2b9 commit 1f7bc54

File tree

4 files changed

+52
-76
lines changed

4 files changed

+52
-76
lines changed

atest/robot/parsing/line_continuation.robot

Lines changed: 22 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@ Resource atest_resource.robot
44

55
*** Test Cases ***
66
Multiline suite documentation and metadata
7-
Should Be Equal ${SUITE.doc} First row.\nSecond row.\n\nSecond paragraph\n!\n!\n!
7+
Should Be Equal ${SUITE.doc} First row.\nSecond row.\n\nSecond paragraph\n!
88
Should Be Equal ${SUITE.metadata['Name']} 1.1\n1.2\n\n2.1\n2.2\n2.3\n\n3.1
99

1010
Multiline suite level settings
1111
Should Contain Tags ${SUITE.tests[0]}
1212
... ... t1 t2 t3 t4 t5 t6 t7 t8 t9
1313
Check Log Message ${SUITE.tests[0].teardown.msgs[0]} 1st
14-
Check Log Message ${SUITE.tests[0].teardown.msgs[1]} 2nd last
15-
Length Should Be ${SUITE.tests[0].teardown.msgs} 2
14+
Check Log Message ${SUITE.tests[0].teardown.msgs[1]} ${EMPTY}
15+
Check Log Message ${SUITE.tests[0].teardown.msgs[2]} 2nd last
16+
Check Log Message ${SUITE.tests[0].teardown.msgs[3]} ${EMPTY}
17+
Length Should Be ${SUITE.tests[0].teardown.msgs} 4
1618

1719
Multiline import
1820
Check Test Case ${TEST NAME}
@@ -25,16 +27,18 @@ Multiline arguments with library keyword
2527
Check Log Message ${tc.kws[0].msgs[0]} one
2628
Check Log Message ${tc.kws[0].msgs[1]} two
2729
Check Log Message ${tc.kws[0].msgs[2]} three
28-
Check Log Message ${tc.kws[0].msgs[3]} four
29-
Check Log Message ${tc.kws[0].msgs[4]} five
30+
Check Log Message ${tc.kws[0].msgs[3]} ${EMPTY}
31+
Check Log Message ${tc.kws[0].msgs[4]} four
32+
Check Log Message ${tc.kws[0].msgs[5]} five
3033

3134
Multiline arguments with user keyword
3235
${tc} = Check Test Case ${TEST NAME}
3336
Check Log Message ${tc.kws[0].kws[0].msgs[0]} 1
34-
Check Log Message ${tc.kws[0].kws[0].msgs[1]} 2
35-
Check Log Message ${tc.kws[0].kws[0].msgs[2]} 3
36-
Check Log Message ${tc.kws[0].kws[0].msgs[3]} 4
37-
Check Log Message ${tc.kws[0].kws[0].msgs[4]} 5
37+
Check Log Message ${tc.kws[0].kws[0].msgs[1]} ${EMPTY}
38+
Check Log Message ${tc.kws[0].kws[0].msgs[2]} 2
39+
Check Log Message ${tc.kws[0].kws[0].msgs[3]} 3
40+
Check Log Message ${tc.kws[0].kws[0].msgs[4]} 4
41+
Check Log Message ${tc.kws[0].kws[0].msgs[5]} 5
3842

3943
Multiline assignment
4044
Check Test Case ${TEST NAME}
@@ -48,7 +52,8 @@ Multiline test settings
4852
Should Contain Tags ${tc} @{expected}
4953
Should Be Equal ${tc.doc} One.\nTwo.\nThree.\n\nSecond paragraph.
5054
Check Log Message ${tc.setup.msgs[0]} first
51-
Check Log Message ${tc.setup.msgs[1]} last
55+
Check Log Message ${tc.setup.msgs[1]} ${EMPTY}
56+
Check Log Message ${tc.setup.msgs[2]} last
5257

5358
Multiline user keyword settings
5459
Check Test Case ${TEST NAME}
@@ -59,52 +64,17 @@ Multiline for Loop declaration
5964
Multiline in for loop body
6065
Check Test Case ${TEST NAME}
6166

62-
Escaped empty cells before line continuation are deprecated
63-
[Template] Check Escaped Leading Empty Cell Deprecation
64-
1
65-
10
66-
12
67-
68-
Line continuation without value is deprecated
69-
[Documentation] Except for Documentation and Metadata
70-
[Template] Check Line Continuation Alone Deprecation
71-
2 In 'Default Tags' setting
72-
3 In 'Test Teardown' setting
73-
4 In 'Test Teardown' setting
74-
5 In 'Variables' section
75-
6 In 'Variables' section
76-
7 In 'Variables' section
77-
8 In 'Variables' section
78-
9 Invalid syntax in test case 'Multiline arguments with library keyword'
79-
11 Invalid syntax in test case 'Multiline arguments with user keyword'
80-
13 Invalid syntax in test case 'Multiline test settings': In '[Tags]' setting
81-
14 Invalid syntax in test case 'Multiline test settings': In '[Setup]' setting
82-
15 Invalid syntax in test case 'Invalid usage in test and user keyword'
83-
16 Invalid syntax in keyword 'Multiline user keyword settings': In '[Return]' setting
84-
17 Invalid syntax in keyword 'Invalid usage in UK'
67+
Escaped empty cells before line continuation do not work
68+
Check Error 0 Non-existing setting '\\'.
69+
Check Error 1 Setting variable '\\' failed: Invalid variable name '\\'.
70+
Check Test Case Invalid usage in keyword call
8571

8672
Invalid multiline usage
87-
[Setup] Check Test Case Invalid Usage In Test And User Keyword
88-
[Template] Check Multiline Error
89-
0 Non-existing setting '...'.
90-
-1 Setting variable '...' failed: Invalid variable name '...'.
73+
Check Test Case Invalid Usage In Test
74+
Check Test Case Invalid Usage In User Keyword
9175

9276
*** Keywords ***
93-
Check Escaped Leading Empty Cell Deprecation
94-
[Arguments] ${index}
95-
${message} = Catenate
96-
... Escaping empty cells with '\\' before line continuation marker '...'
97-
... is deprecated. Remove escaping before Robot Framework 3.2.
98-
Check Multiline Error ${index} ${message} WARN
99-
100-
Check Line Continuation Alone Deprecation
101-
[Arguments] ${index} ${prefix}
102-
${message} = Catenate
103-
... ${prefix}:
104-
... Ignoring lines with only continuation marker '...' is deprecated.
105-
Check Multiline Error ${index} ${message} WARN
106-
107-
Check Multiline Error
77+
Check Error
10878
[Arguments] ${index} ${message} ${level}=ERROR
10979
${path} = Normalize Path ${DATADIR}/parsing/line_continuation.robot
11080
Check Log Message ${ERRORS}[${index}]

atest/testdata/parsing/line_continuation.robot

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
... Ignored usage
22

33
*** Settings ***
4-
... Invalid usage
4+
... Part of header above
55
Documentation
66
... First row.
77
... Second row.
88
...
99
... Second paragraph
1010
... !
11-
\ ... ! # Leading '\' deprecated in RF 3.1.2.
11+
\ ... Does not work anymore in RF 3.2.
1212
... !
1313
Metadata Name
1414
... 1.1
@@ -34,12 +34,13 @@ Test Teardown Log Many
3434
...
3535

3636
*** Variables ***
37-
... # Invalid usage
37+
... # Part of header above
3838
${STRING} first
3939
...
4040
... third
41-
... # Ignoring empty
41+
... # Not ignoring empty
4242
# Comments, comments, comments, ...
43+
\ ... Does not work anymore in RF 3.2.
4344
@{list} ... hello
4445
... world
4546
...
@@ -51,20 +52,20 @@ Multiline import
5152
Directory Should Exist .
5253

5354
Multiline variables
54-
Should Be Equal ${STRING} first third
55+
Should Be Equal ${STRING} first${SPACE * 2}third${SPACE}
5556
Should Be True $LIST ['...', 'hello', 'world', '...', '!!!']
5657

5758
Multiline arguments with library keyword
5859
Log Many one two
5960
... three
6061
...
61-
\ ... four five # Leading '\' deprecated in RF 3.1.2.
62+
... four five
6263

6364
Multiline arguments with user keyword
6465
UK Log Many
6566
... ${1}
6667
...
67-
... ${2} ${3}
68+
... ${2} ${3}
6869
... ${4}
6970
... ${5}
7071

@@ -84,9 +85,9 @@ Multiline in user keyword
8485
Multiline test settings
8586
[Documentation] One.
8687
... Two.
87-
\ ... Three. # Leading '\' deprecated in RF 3.1.2.
88+
... Three.
8889
...
89-
... Second paragraph.
90+
... Second paragraph.
9091
[Tags]
9192
... my1 my2 my3
9293
... my4
@@ -100,12 +101,12 @@ Multiline test settings
100101

101102
Multiline user keyword settings
102103
${x} = Multiline User Keyword Settings 1 2
103-
Should Be True ${x} == [str(i) for i in range(1,10) if i != 8]
104+
Should Be True ${x} == [str(i) if i != 8 else '' for i in range(1,10)]
104105
${x} = Multiline User Keyword Settings
105106
... 1 2 3 4 5 r1 r2 r3
106107
Should Be True ${x[:5]} == [str(i) for i in range(1,6)]
107108
Should Be True ${x[5:8]} == ['r1','r2','r3']
108-
Should Be True ${x[9:]} == ['7', '9']
109+
Should Be True ${x[9:]} == ['7', '', '9']
109110

110111
Multiline for Loop declaration
111112
${result} = Set Variable ${EMPTY}
@@ -164,11 +165,21 @@ Multiline in for loop body
164165
Should Be Equal ${result} ABC
165166
Should Be Equal ${x} 1 2 3 a b c
166167

167-
Invalid usage in test and user keyword
168+
Invalid usage in test
168169
...
169-
[Documentation] FAIL This is executed after all!
170+
[Documentation] FAIL Keyword name cannot be empty.
171+
No operation
172+
173+
Invalid usage in user keyword
174+
[Documentation] FAIL Keyword name cannot be empty.
170175
Invalid Usage In UK
171176

177+
Invalid usage in keyword call
178+
[Documentation] FAIL No keyword with name '\\' found.
179+
Log Many 1
180+
... 2
181+
\ ... Does not work anymore in 3.2
182+
172183
*** Keywords ***
173184
UK log many
174185
[Arguments] @{msgs}
@@ -209,4 +220,4 @@ Multiline user keyword settings
209220

210221
Invalid usage in UK
211222
...
212-
Fail This is executed after all!
223+
No operation

src/robot/parsing/lexer/lexers.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,9 @@ def _handle_name_or_indentation(self, statement):
253253
if not self._name_set:
254254
statement.pop(0).type = Token.NAME
255255
self._name_set = True
256-
while statement and not statement[0].value:
257-
statement.pop(0).type = Token.IGNORE
256+
else:
257+
while statement and not statement[0].value:
258+
statement.pop(0).type = Token.IGNORE
258259

259260
def _handle_old_style_for_loop(self, statement, lexer):
260261
# TODO: Deprecation
@@ -297,7 +298,7 @@ class TestOrKeywordSettingLexer(SettingLexer):
297298
@classmethod
298299
def handles(cls, statement):
299300
marker = statement[0].value
300-
return marker[0] == '[' and marker[-1] == ']'
301+
return marker and marker[0] == '[' and marker[-1] == ']'
301302

302303

303304
class ForLoopLexer(StatementLexer):
@@ -306,7 +307,7 @@ class ForLoopLexer(StatementLexer):
306307
def handles(cls, statement):
307308
marker = statement[0].value
308309
return (marker == 'FOR' or
309-
marker[0] == ':' and
310+
marker.startswith(':') and
310311
marker.replace(':', '').replace(' ', '').upper() == 'FOR')
311312

312313
def lex(self, ctc):

src/robot/parsing/lexer/splitter.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,6 @@ def _handle_continuation(self, tokens):
9292
if token.value == '...' and token.type == token.DATA:
9393
token.type = token.CONTINUATION
9494
return True
95-
# TODO: Remove when old for is removed
96-
elif token.value == '\\':
97-
continue
9895
elif token.value and token.type != token.SEPARATOR:
9996
return False
10097
return False
@@ -111,9 +108,6 @@ def _remove_leading_empty(self, tokens):
111108
for token in list(tokens):
112109
if not token.value:
113110
tokens.remove(token)
114-
# TODO: Remove when old for is removed
115-
elif token.value == '\\':
116-
tokens.remove(token)
117111
elif token.type in (token.DATA, token.CONTINUATION):
118112
return
119113

0 commit comments

Comments
 (0)