26 from .model
import ForLoop, Keyword, ResourceFile, TestSuite
50 def __init__(self, include_suites=None, warn_on_skipped='DEPRECATED',
51 extension=None, rpa=None):
60 if warn_on_skipped !=
'DEPRECATED':
61 warnings.warn(
"Option 'warn_on_skipped' is deprecated and has no "
62 "effect.", DeprecationWarning)
67 extensions = set(ext.lower().lstrip(
'.')
for ext
in extension.split(
':'))
68 if not all(ext
in TEST_EXTENSIONS
for ext
in extensions):
69 raise DataError(
"Invalid extension to limit parsing '%s'." % extension)
78 raise DataError(
'One or more source paths required.')
84 root.rpa = self.
rparpa
89 suite.remove_empty_suites()
97 except DataError
as err:
98 raise DataError(
"Parsing '%s' failed: %s" % (path, err.message))
101 if self.
_rpa_not_given_rpa_not_given
and data.testcase_table.is_started():
104 defaults =
TestDefaults(data.setting_table, parent_defaults)
107 doc=
unic(data.setting_table.doc),
108 metadata=self.
_get_metadata_get_metadata(data.setting_table))
109 self.
_build_setup_build_setup(suite, data.setting_table.suite_setup)
110 self.
_build_teardown_build_teardown(suite, data.setting_table.suite_teardown)
111 for test_data
in data.testcase_table.tests:
112 self.
_build_test_build_test(suite, test_data, defaults)
113 for child
in data.children:
114 suite.suites.append(self.
_build_suite_build_suite(child, defaults))
115 suite.rpa = self.
rparpa
120 rpa =
normalize(data.testcase_table.header[0])
in (
'task',
'tasks')
121 if self.
rparpa
is None:
123 elif self.
rparpa
is not rpa:
124 this, that = (
'tasks',
'tests')
if rpa
else (
'tests',
'tasks')
125 raise DataError(
"Conflicting execution modes. File '%s' has %s "
126 "but files parsed earlier have %s. Fix headers "
127 "or use '--rpa' or '--norpa' options to set the "
128 "execution mode explicitly."
129 % (data.source, this, that))
132 if os.path.isdir(source):
134 ext = os.path.splitext(source)[1][1:].
lower()
139 if ext
not in (
'robot',
'html',
'htm',
'xhtml'):
140 LOGGER.warn(
"Automatically parsing other than '*.robot' files is "
141 "deprecated. Convert '%s' to '*.robot' format or use "
142 "'--extension' to explicitly configure which files to "
147 return [(meta.name, meta.value)
for meta
in settings.metadata]
150 values = defaults.get_test_values(data)
152 test = suite.tests.create(name=data.name,
154 tags=values.tags.value,
162 return (timeout.value, timeout.message)
if timeout
else None
165 return unic(template)
if template.is_active()
else None
169 self.
_build_step_build_step(parent, data, kw_type=
'setup')
173 self.
_build_step_build_step(parent, data, kw_type=
'teardown')
183 def build(self, path_or_data, target=None):
186 target =
ResourceFile(doc=data.setting_table.doc.value, source=source)
187 self.
_build_imports_build_imports(target, data.setting_table.imports)
188 self.
_build_variables_build_variables(target, data.variable_table.variables)
189 for kw_data
in data.keyword_table.keywords:
195 return path_or_data, path_or_data.source
196 return ResourceData(path_or_data).populate(), path_or_data
200 target.imports.create(type=data.type,
202 args=tuple(data.args),
206 for data
in variables:
208 target.variables.create(name=data.name, value=data.value)
211 kw = target.keywords.create(name=data.name,
212 args=tuple(data.args),
214 tags=tuple(data.tags),
215 return_=tuple(data.return_),
218 if data.teardown.is_active():
219 self.
_build_step_build_step(kw, data.teardown, kw_type=
'teardown')
222 return (timeout.value, timeout.message)
if timeout
else None
228 steps = [self.
_build_build(step, template, kw_type)
for step
in data.steps
229 if step
and not step.is_comment()]
230 parent.keywords.extend(steps)
232 def build_step(self, parent, data, template=None, kw_type='kw'):
233 if data
and not data.is_comment():
234 step = self.
_build_build(data, template, kw_type)
235 parent.keywords.append(step)
237 def _build(self, data, template=None, kw_type='kw'):
238 if data.is_for_loop():
245 loop =
ForLoop(variables=data.vars,
252 args = data.as_list(include_comment=
False)
254 return Keyword(name=template, args=args)
257 iterator = VariableIterator(template, identifiers=
'$')
258 variables = len(iterator)
259 if not variables
or variables != len(args):
260 return template, tuple(args)
262 for before, variable, after
in iterator:
263 temp.extend([before, args.pop(0)])
265 return ''.join(temp), ()
269 args=tuple(data.args),
270 assign=tuple(data.assign),
Used when variable does not exist.
The parsed resource file object.
def _build_keyword(self, target, data)
def _import_resource_if_needed(self, path_or_data)
def _build_imports(self, target, imports)
def _get_timeout(self, timeout)
def _build_variables(self, target, variables)
def build(self, path_or_data, target=None)
def _format_template(self, template, args)
def _build_normal_step(self, data, kw_type)
def build_step(self, parent, data, template=None, kw_type='kw')
def _build_for_loop(self, data, template)
def _build(self, data, template=None, kw_type='kw')
def build_steps(self, parent, data, template=None, kw_type='kw')
def _build_templated_step(self, data, template)
Creates executable :class:~robot.running.model.TestSuite objects.
def _get_extensions(self, extension)
def _build_teardown(self, parent, data)
def _get_template(self, template)
def _build_setup(self, parent, data)
def build(self, *paths)
:param paths: Paths to test data files or directories.
def _get_metadata(self, settings)
def _build_test(self, suite, data, defaults)
def _parse_and_build(self, path)
def _get_timeout(self, timeout)
def _set_execution_mode(self, data)
def _build_suite(self, data, parent_defaults=None)
def __init__(self, include_suites=None, warn_on_skipped='DEPRECATED', extension=None, rpa=None)
:param include_suites: List of suite names to include.
def _check_deprecated_extensions(self, source)
Represents a for loop in test data.
Represents a single executable keyword.
Represents a single executable test suite.
def TestData(source, parent=None, settings=None)
Parses a file or directory to a corresponding model object.
def normalize(string, ignore=(), caseless=True, spaceless=True)
Normalizes given string according to given spec.
def abspath(path, case_normalize=False)
Replacement for os.path.abspath with some enhancements and bug fixes.