Skip to content

Commit 3c7f25f

Browse files
committed
Parsing plugins
1 parent 86eae82 commit 3c7f25f

File tree

6 files changed

+67
-14
lines changed

6 files changed

+67
-14
lines changed

atest/tests.robot

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
*** Settings ***
22
Library ${LIBRARY}.py
33

4+
45
*** Variables ***
56
${LIBRARY} DynamicLibrary
67

8+
79
*** Test Cases ***
810
Keyword names
911
Keyword in main
@@ -12,9 +14,7 @@ Keyword names
1214
Method
1315
Custom name
1416
Cust omna me
15-
IF $LIBRARY == "ExtendExistingLibrary"
16-
Keyword in extending library
17-
END
17+
IF $LIBRARY == "ExtendExistingLibrary" Keyword in extending library
1818

1919
Method without @keyword are not keyowrds
2020
[Documentation] FAIL GLOB: No keyword with name 'Not keyword' found.*
@@ -45,6 +45,7 @@ Embedded arguments
4545
Embedded arguments "work"
4646
embeDded ArgumeNtS "Work but this fails"
4747

48+
4849
*** Keywords ***
4950
Return value should be
5051
[Arguments] ${expected} ${keyword} @{args} &{kwargs}

atest/tests_types.robot

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
Library DynamicTypesLibrary.py
33
Library DynamicTypesAnnotationsLibrary.py xxx
44

5+
56
*** Variables ***
67
${CUSTOM NONE} = ${None}
78

9+
810
*** Test Cases ***
911
Keyword Default Argument As Abject None
1012
${return} = DynamicTypesLibrary.Keyword None ${None}
@@ -56,7 +58,8 @@ Varargs and KeywordArgs With Typing Hints
5658
... 1 2 3 4 # varargs
5759
... other=True # other argument
5860
... key1=1 key2=2 # kwargs
59-
Should Match ${return}
61+
Should Match
62+
... ${return}
6063
... this_is_mandatory: <class 'str'>, (1, 2, 3, 4): <class 'tuple'>, True: <class 'bool'>, {'key1': 1, 'key2': 2}: <class 'dict'>
6164

6265
Enum Conversion Should Work
@@ -109,9 +112,8 @@ Python 3.10 New Type Hints
109112
Should Be Equal ${types} arg: {"key": 1}, type: <class 'str'>
110113
END
111114

115+
112116
*** Keywords ***
113117
Import DynamicTypesAnnotationsLibrary In Python 3.10 Only
114118
${py3} = DynamicTypesLibrary.Is Python 3 10
115-
IF ${py3}
116-
Import Library Python310Library.py
117-
END
119+
IF ${py3} Import Library Python310Library.py

src/robotlibcore.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -285,24 +285,28 @@ def __init__(self, argument_specification=None, documentation=None, argument_typ
285285

286286

287287
class PluginParser:
288+
def __init__(self, base_class: typing.Any):
289+
self._base_class = base_class
288290

289291
def parse_plugins(self, plugins: str) -> typing.List:
290-
libraries = []
292+
imported_plugins = []
291293
importer = Importer("test library")
292294
for parsed_plugin in self._string_to_modules(plugins):
293295
plugin = importer.import_class_or_module(parsed_plugin.module)
294296
if not inspect.isclass(plugin):
295297
message = f"Importing test library: '{parsed_plugin.module}' failed."
296298
raise DataError(message)
297-
plugin = plugin(self, *parsed_plugin.args, **parsed_plugin.kw_args)
298-
if not isinstance(plugin, LibraryComponent):
299+
plugin = plugin(*parsed_plugin.args, **parsed_plugin.kw_args)
300+
if self._base_class and not isinstance(plugin, self._base_class):
299301
message = (
300302
"Plugin does not inherit SeleniumLibrary.base.LibraryComponent"
301303
)
302304
raise PluginError(message)
303-
self._store_plugin_keywords(plugin)
304-
libraries.append(plugin)
305-
return libraries
305+
imported_plugins.append(plugin)
306+
return imported_plugins
307+
308+
def get_plugin_keyword(self, plugins: typing.List):
309+
pass
306310

307311
def _string_to_modules(self, modules):
308312
parsed_modules = []

utest/helpers/my_plugin_test.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from robot.api.deco import keyword
2+
3+
4+
class TestClass:
5+
6+
@keyword
7+
def new_keyword(self, arg: int) -> int:
8+
return arg + self.not_keyword()
9+
10+
def not_keyword(self):
11+
return 1
12+
13+
14+
class LibraryBase:
15+
16+
def __init__(self):
17+
self.x = 1
18+
19+
def base(self):
20+
return 2
21+
22+
23+
class TestClassWithBase(LibraryBase):
24+
25+
@keyword
26+
def another_keywor(self) -> int:
27+
return 2 * 2
28+
29+
def normal_method(self):
30+
return "xxx"

utest/run.py

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
src = join(curdir, "..", "src")
1515
sys.path.insert(0, src)
1616
sys.path.insert(0, atest_dir)
17+
helpers = join(curdir, "helpers")
18+
sys.path.append(helpers)
1719

1820
parser = argparse.ArgumentParser()
1921
parser.add_argument("--no-cov", dest="cov", action="store_false")
@@ -22,6 +24,7 @@
2224
args = parser.parse_args()
2325

2426
pytest_args = [
27+
f"--ignore={helpers}",
2528
"-p",
2629
"no:cacheprovider",
2730
"--junitxml=%s" % xunit_report,

utest/test_plugin_api.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import pytest
22

33
from robotlibcore import Module, PluginParser
4+
import my_plugin_test
45

56

67
@pytest.fixture(scope="module")
78
def plugin_parser() -> PluginParser:
8-
return PluginParser()
9+
return PluginParser(None)
910

1011

1112
def test_no_plugins_parsing(plugin_parser):
@@ -35,3 +36,15 @@ def test_plugins_string_to_modules(plugin_parser):
3536
assert result == [
3637
Module("PluginWithKwArgs.py", [], {"kw1": "Text1", "kw2": "Text2"}),
3738
]
39+
40+
41+
def test_parse_plugins(plugin_parser):
42+
plugins = plugin_parser.parse_plugins("my_plugin_test.TestClass")
43+
assert len(plugins) == 1
44+
assert isinstance(plugins[0], my_plugin_test.TestClass)
45+
plugins = plugin_parser.parse_plugins("my_plugin_test.TestClass,my_plugin_test.TestClassWithBase")
46+
assert len(plugins) == 2
47+
assert isinstance(plugins[0], my_plugin_test.TestClass)
48+
assert isinstance(plugins[1], my_plugin_test.TestClassWithBase)
49+
50+

0 commit comments

Comments
 (0)