Skip to content

Commit 63f701b

Browse files
committed
Test visiting and modifying parsing model
1 parent 0e75591 commit 63f701b

File tree

1 file changed

+170
-1
lines changed

1 file changed

+170
-1
lines changed

utest/parsing/test_model.py

Lines changed: 170 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import unittest
44
import tempfile
55

6-
from robot.parsing import get_model, Token
6+
from robot.parsing import get_model, ModelVisitor, ModelTransformer, Token
77
from robot.parsing.model.blocks import (
88
Block, File, CommentSection, TestCaseSection, KeywordSection,
99
TestCase, Keyword
@@ -218,5 +218,174 @@ def test_save_to_original_fails_if_source_is_not_path(self):
218218
assert_raises_with_msg(TypeError, message, get_model(f).save)
219219

220220

221+
class TestModelVisitors(unittest.TestCase):
222+
223+
def test_ast_NodevVisitor(self):
224+
225+
class Visitor(ast.NodeVisitor):
226+
227+
def __init__(self):
228+
self.test_names = []
229+
self.kw_names = []
230+
self.names = None
231+
232+
def visit_TestCaseSection(self, node):
233+
self.names = self.test_names
234+
self.generic_visit(node)
235+
236+
def visit_KeywordSection(self, node):
237+
self.names = self.kw_names
238+
self.generic_visit(node)
239+
240+
def visit_Name(self, node):
241+
self.names.append(node.name)
242+
243+
def visit_Block(self, node):
244+
raise RuntimeError('Should not be executed.')
245+
246+
def visit_Statement(self, node):
247+
raise RuntimeError('Should not be executed.')
248+
249+
visitor = Visitor()
250+
visitor.visit(get_model(DATA))
251+
assert_equal(visitor.test_names, ['Example'])
252+
assert_equal(visitor.kw_names, ['Keyword'])
253+
254+
def test_ModelVisitor(self):
255+
256+
class Visitor(ModelVisitor):
257+
258+
def __init__(self):
259+
self.test_names = []
260+
self.kw_names = []
261+
self.names = None
262+
self.blocks = []
263+
self.statements = []
264+
265+
def visit_TestCaseSection(self, node):
266+
self.names = self.test_names
267+
self.visit_Block(node)
268+
269+
def visit_KeywordSection(self, node):
270+
self.names = self.kw_names
271+
self.visit_Block(node)
272+
273+
def visit_Name(self, node):
274+
self.names.append(node.name)
275+
self.visit_Statement(node)
276+
277+
def visit_Block(self, node):
278+
self.blocks.append(type(node).__name__)
279+
self.generic_visit(node)
280+
281+
def visit_Statement(self, node):
282+
self.statements.append(node.type)
283+
284+
visitor = Visitor()
285+
visitor.visit(get_model(DATA))
286+
assert_equal(visitor.test_names, ['Example'])
287+
assert_equal(visitor.kw_names, ['Keyword'])
288+
assert_equal(visitor.blocks,
289+
['File', 'CommentSection', 'Body',
290+
'TestCaseSection', 'Body', 'TestCase', 'Body',
291+
'KeywordSection', 'Body', 'Keyword', 'Body'])
292+
assert_equal(visitor.statements,
293+
['EOL', 'TESTCASE_HEADER', 'NAME', 'KEYWORD',
294+
'EOL', 'KEYWORD_HEADER', 'NAME', 'ARGUMENTS', 'KEYWORD'])
295+
296+
def test_ast_NodeTransformer(self):
297+
298+
class Transformer(ast.NodeTransformer):
299+
300+
def visit_Tags(self, node):
301+
return None
302+
303+
def visit_TestCaseSection(self, node):
304+
self.generic_visit(node)
305+
node.body.items.append(
306+
TestCase(Name([Token('NAME', 'Added'),
307+
Token('EOL', '\n')])))
308+
return node
309+
310+
def visit_TestCase(self, node):
311+
self.generic_visit(node)
312+
return node if node.name != 'REMOVE' else None
313+
314+
def visit_Name(self, node):
315+
name = node.get_token(Token.NAME)
316+
name.value = name.value.upper()
317+
return node
318+
319+
def visit_Block(self, node):
320+
raise RuntimeError('Should not be executed.')
321+
322+
def visit_Statement(self, node):
323+
raise RuntimeError('Should not be executed.')
324+
325+
model = get_model('''\
326+
*** Test Cases ***
327+
Example
328+
[Tags] to be removed
329+
Remove
330+
''')
331+
Transformer().visit(model)
332+
expected = File([
333+
TestCaseSection(
334+
header=TestCaseSectionHeader([
335+
Token('TESTCASE_HEADER', '*** Test Cases ***', 1, 0),
336+
Token('EOL', '\n', 1, 18)
337+
]),
338+
body=[
339+
TestCase(Name([Token('NAME', 'EXAMPLE', 2, 0),
340+
Token('EOL', '\n', 2, 7)])),
341+
TestCase(Name([Token('NAME', 'Added'),
342+
Token('EOL', '\n')]))
343+
]
344+
)
345+
])
346+
assert_model(model, expected)
347+
348+
def test_ModelTransformer(self):
349+
350+
class Transformer(ModelTransformer):
351+
352+
def visit_TestCaseSectionHeader(self, node):
353+
return node
354+
355+
def visit_Name(self, node):
356+
return node
357+
358+
def visit_Statement(self, node):
359+
return None
360+
361+
def visit_Block(self, node):
362+
self.generic_visit(node)
363+
if hasattr(node, 'header'):
364+
for token in node.header.data_tokens:
365+
token.value = token.value.upper()
366+
return node
367+
368+
model = get_model('''\
369+
*** Test Cases ***
370+
Example
371+
[Tags] to be removed
372+
To be removed
373+
''')
374+
Transformer().visit(model)
375+
expected = File([
376+
TestCaseSection(
377+
header=TestCaseSectionHeader([
378+
Token('TESTCASE_HEADER', '*** TEST CASES ***', 1, 0),
379+
Token('EOL', '\n', 1, 18)
380+
]),
381+
body=[
382+
TestCase(Name([Token('NAME', 'Example', 2, 0),
383+
Token('EOL', '\n', 2, 7)])),
384+
]
385+
)
386+
])
387+
assert_model(model, expected)
388+
389+
221390
if __name__ == '__main__':
222391
unittest.main()

0 commit comments

Comments
 (0)