Skip to content

Commit

Permalink
Enhance programmatic API to create resource files
Browse files Browse the repository at this point in the history
Enhancements to `ResourceFile`:
- Expose via `robot.running`.
- Add `from_file_system`, `from_string` and `from_model`.

Fixes #4793.
  • Loading branch information
pekkaklarck committed Jun 11, 2023
1 parent cf3ec9b commit 4f9e8d2
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/robot/running/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
from .builder import ResourceFileBuilder, TestDefaults, TestSuiteBuilder
from .context import EXECUTION_CONTEXTS
from .model import (Break, Continue, Error, For, If, IfBranch, Keyword, Return,
TestCase, TestSuite, Try, TryBranch, While)
ResourceFile, TestCase, TestSuite, Try, TryBranch, While)
from .runkwregister import RUN_KW_REGISTER
from .testlibraries import TestLibrary
from .usererrorhandler import UserErrorHandler
Expand Down
7 changes: 6 additions & 1 deletion src/robot/running/builder/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ def _get_source(self, source: Path) -> 'Path|str':
def parse_resource_file(self, source: Path) -> ResourceFile:
model = get_resource_model(self._get_source(source), data_only=True,
curdir=self._get_curdir(source), lang=self.lang)
resource = ResourceFile(source=source)
resource = self.parse_resource_model(model)
resource.source = source
return resource

def parse_resource_model(self, model: File) -> ResourceFile:
resource = ResourceFile(source=model.source)
ResourceBuilder(resource).build(model)
return resource

Expand Down
44 changes: 44 additions & 0 deletions src/robot/running/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,50 @@ def variables(self, variables: Sequence['Variable']) -> 'Variables':
def keywords(self, keywords: Sequence['UserKeyword']) -> 'UserKeywords':
return UserKeywords(self, keywords)

@classmethod
def from_file_system(cls, path: 'Path|str', **config) -> 'ResourceFile':
"""Create a :class:`ResourceFile` object based on the give ``path``.
:param path: File path where to read the data from.
:param config: Configuration parameters for :class:`~.builders.ResourceFileBuilder`
class that is used internally for building the suite.
New in Robot Framework 6.1. See also :meth:`from_string` and :meth:`from_model`.
"""
from .builder import ResourceFileBuilder
return ResourceFileBuilder(**config).build(path)

@classmethod
def from_string(cls, string: str, **config) -> 'ResourceFile':
"""Create a :class:`ResourceFile` object based on the given ``string``.
:param string: String to create the resource file from.
:param config: Configuration parameters for
:func:`~robot.parsing.parser.parser.get_resource_model` used internally.
New in Robot Framework 6.1. See also :meth:`from_file_system` and
:meth:`from_model`.
"""
from robot.parsing import get_resource_model
model = get_resource_model(string, data_only=True, **config)
return cls.from_model(model)

@classmethod
def from_model(cls, model: 'File') -> 'ResourceFile':
"""Create a :class:`ResourceFile` object based on the given ``model``.
:param model: Model to create the suite from.
The model can be created by using the
:func:`~robot.parsing.parser.parser.get_resource_model` function and possibly
modified by other tooling in the :mod:`robot.parsing` module.
New in Robot Framework 6.1. See also :meth:`from_file_system` and
:meth:`from_string`.
"""
from .builder import RobotParser
return RobotParser().parse_resource_model(model)

def to_dict(self) -> DataDict:
data = {}
if self._source:
Expand Down
4 changes: 3 additions & 1 deletion utest/resources/test.resource
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
*** Keywords ***
*** Variables ***
${PATH} ${CURDIR}

*** Keywords ***
My Test Keyword
No Operation
62 changes: 59 additions & 3 deletions utest/running/test_run_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@

from robot import api, model
from robot.model.modelobject import ModelObject
from robot.parsing import get_resource_model
from robot.running import (Break, Continue, Error, For, If, IfBranch, Keyword,
Return, TestCase, TestDefaults, TestSuite, Try, TryBranch,
While)
from robot.running.model import ResourceFile, UserKeyword
Return, ResourceFile, TestCase, TestDefaults, TestSuite,
Try, TryBranch, While)
from robot.running.model import UserKeyword
from robot.utils.asserts import (assert_equal, assert_false, assert_not_equal,
assert_raises, assert_true)

Expand Down Expand Up @@ -520,5 +521,60 @@ def _create_suite_structure(self, obj):
return suite


class TestResourceFile(unittest.TestCase):
path = CURDIR.parent / 'resources/test.resource'
data = '''
*** Settings ***
Library Example
Keyword Tags common
*** Variables ***
${NAME} Value
*** Keywords ***
Example
[Tags] own
Log Hello!
'''

def test_from_file_system(self):
res = ResourceFile.from_file_system(self.path)
assert_equal(res.variables[0].name, '${PATH}')
assert_equal(res.variables[0].value, (str(self.path.parent).replace('\\', '\\\\'),))
assert_equal(res.keywords[0].name, 'My Test Keyword')

def test_from_file_system_with_config(self):
res = ResourceFile.from_file_system(self.path, process_curdir=False)
assert_equal(res.variables[0].name, '${PATH}')
assert_equal(res.variables[0].value, ('${CURDIR}',))
assert_equal(res.keywords[0].name, 'My Test Keyword')

def test_from_string(self):
res = ResourceFile.from_string(self.data)
assert_equal(res.imports[0].name, 'Example')
assert_equal(res.variables[0].name, '${NAME}')
assert_equal(res.variables[0].value, ('Value',))
assert_equal(res.keywords[0].name, 'Example')
assert_equal(res.keywords[0].tags, ['common', 'own'])
assert_equal(res.keywords[0].body[0].name, 'Log')
assert_equal(res.keywords[0].body[0].args, ('Hello!',))

def test_from_string_with_config(self):
res = ResourceFile.from_string('*** Muuttujat ***\n${NIMI}\tarvo', lang='fi')
assert_equal(res.variables[0].name, '${NIMI}')
assert_equal(res.variables[0].value, ('arvo',))

def test_from_model(self):
model = get_resource_model(self.data)
res = ResourceFile.from_model(model)
assert_equal(res.imports[0].name, 'Example')
assert_equal(res.variables[0].name, '${NAME}')
assert_equal(res.variables[0].value, ('Value',))
assert_equal(res.keywords[0].name, 'Example')
assert_equal(res.keywords[0].tags, ['common', 'own'])
assert_equal(res.keywords[0].body[0].name, 'Log')
assert_equal(res.keywords[0].body[0].args, ('Hello!',))


if __name__ == '__main__':
unittest.main()

0 comments on commit 4f9e8d2

Please sign in to comment.