Skip to content

Commit

Permalink
parsing: report empty test name during parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
yanne committed Jan 18, 2023
1 parent dbc42be commit 86fd5d4
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 16 deletions.
15 changes: 9 additions & 6 deletions src/robot/parsing/model/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from robot.utils import file_writer, is_pathlike, is_string

from .statements import Comment, EmptyLine
from .statements import KeywordCall, TemplateArguments, Continue, Break, Return
from .visitor import ModelVisitor
from ..lexer import Token

Expand Down Expand Up @@ -54,10 +54,8 @@ def validate(self, context):
pass

def _body_is_empty(self):
for node in self.body:
if not isinstance(node, (EmptyLine, Comment)):
return False
return True
valid = (KeywordCall, TemplateArguments, Continue, Return, Break, For, If, While, Try)
return not any(isinstance(node, valid) for node in self.body)


class HeaderAndBody(Block):
Expand Down Expand Up @@ -127,14 +125,19 @@ class CommentSection(Section):
class TestCase(Block):
_fields = ('header', 'body')

def __init__(self, header, body=None):
def __init__(self, header, body=None, errors=()):
self.header = header
self.body = body or []
self.errors = errors

@property
def name(self):
return self.header.name

def validate(self, context):
if self._body_is_empty():
self.errors += ('Test contains no keywords.',)


class Keyword(Block):
_fields = ('header', 'body')
Expand Down
4 changes: 4 additions & 0 deletions src/robot/parsing/model/statements.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,10 @@ def from_params(cls, name, eol=EOL):
def name(self):
return self.get_value(Token.TESTCASE_NAME)

def validate(self, context):
if not self.name:
self.errors += (f'Test name cannot be empty.',)


@Statement.register
class KeywordName(Statement):
Expand Down
3 changes: 2 additions & 1 deletion src/robot/running/builder/transformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ def __init__(self, suite: TestSuite, defaults: Defaults):
self.test = None

def visit_TestCase(self, node):
self.test = self.suite.tests.create(name=node.name, lineno=node.lineno)
self.test = self.suite.tests.create(name=node.name, lineno=node.lineno,
error=format_error(node.errors + node.header.errors))
self.generic_visit(node)
self._set_settings(self.test, self.settings)

Expand Down
7 changes: 5 additions & 2 deletions src/robot/running/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,16 +327,17 @@ class TestCase(model.TestCase):
See the base class for documentation of attributes not documented here.
"""
__slots__ = ['template']
__slots__ = ['template', 'error']
body_class = Body #: Internal usage only.
fixture_class = Keyword #: Internal usage only.

def __init__(self, name='', doc='', tags=None, timeout=None, template=None,
lineno=None):
lineno=None, error=None):
super().__init__(name, doc, tags, timeout, lineno)
#: Name of the keyword that has been used as a template when building the test.
# ``None`` if template is not used.
self.template = template
self.error = error

@property
def source(self):
Expand All @@ -346,6 +347,8 @@ def to_dict(self):
data = super().to_dict()
if self.template:
data['template'] = self.template
if self.error:
data['error'] = self.error
return data


Expand Down
9 changes: 3 additions & 6 deletions src/robot/running/suiterunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,9 @@ def visit_test(self, test):
self._add_exit_combine()
result.tags.add('robot:exit')
if status.passed:
if not test.name:
status.test_failed(
test_or_task('{Test} name cannot be empty.', settings.rpa))
elif not test.body:
status.test_failed(
test_or_task('{Test} contains no keywords.', settings.rpa))
if test.error:
error = test.error if not settings.rpa else test.error.replace('Test', 'Task')
status.test_failed(error)
elif test.tags.robot('skip'):
status.test_skipped(
test_or_task("{Test} skipped using 'robot:skip' tag.",
Expand Down
2 changes: 1 addition & 1 deletion utest/parsing/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,7 @@ def visit_Statement(self, node):
TestCase(TestCaseName([
Token('TESTCASE NAME', 'EXAMPLE', 2, 0),
Token('EOL', '\n', 2, 7)
])),
]), errors= ('Test contains no keywords.',)),
TestCase(TestCaseName([
Token('TESTCASE NAME', 'Added'),
Token('EOL', '\n')
Expand Down

0 comments on commit 86fd5d4

Please sign in to comment.