diff --git a/src/oxygen/base_handler.py b/src/oxygen/base_handler.py
index c9d5305..a0eb4e0 100644
--- a/src/oxygen/base_handler.py
+++ b/src/oxygen/base_handler.py
@@ -1,5 +1,8 @@
import re
+from inspect import signature, Parameter
+
+from oxygen.errors import MismatchArgumentException
from .robot_interface import (RobotInterface, get_keywords_from,
set_special_keyword)
@@ -100,14 +103,42 @@ def _build_results(self, keyword, setup_keyword, teardown_keyword):
setup_keyword: The special oxygen setup wrapper
teardown_keyword: The special oxygen teardown wrapper
'''
- test = keyword.parent
- test_results = self.parse_results(self.run_time_data)
- end_time, result_suite = self._interface.result.build_suite(100000,
- test_results)
+ accepted_params = signature(self.parse_results).parameters
+ accepted_params_max = len(accepted_params)
+ accepted_params_min = len([
+ n for n, v in accepted_params.items()
+ if v.default == Parameter.empty])
+ is_multiple_inputs = isinstance(self.run_time_data, tuple)
+
+ # there are multiple inputs and in the range of accepted min and max
+ if is_multiple_inputs and (accepted_params_min <= len(
+ self.run_time_data) <= accepted_params_max):
+ test_results = self.parse_results(*self.run_time_data)
+
+ # there is single input and one required, also can be more non-required
+ elif not is_multiple_inputs and accepted_params_min == 1:
+ test_results = self.parse_results(self.run_time_data)
+
+ # else if there are multiple inputs and not in the range of accepted
+ elif is_multiple_inputs:
+ raise MismatchArgumentException(
+ f'parse_results expects at least {accepted_params_min} and'
+ f' at most {accepted_params_max} arguments '
+ f'but got {len(self.run_time_data)}')
+
+ # at this point there could be only multiple required and single input
+ else:
+ raise MismatchArgumentException(
+ f'parse_results expects at least {accepted_params_min} '
+ 'arguments but got 1')
+
+ _, result_suite = self._interface.result.build_suite(
+ 100000, test_results)
if not result_suite:
return
+ test = keyword.parent
self._set_suite_tags(result_suite, *(self._tags + list(test.tags)))
if setup_keyword:
diff --git a/src/oxygen/errors.py b/src/oxygen/errors.py
index d62f44e..932a080 100644
--- a/src/oxygen/errors.py
+++ b/src/oxygen/errors.py
@@ -24,3 +24,7 @@ class ResultFileNotFoundException(Exception):
class ResultFileIsNotAFileException(Exception):
pass
+
+
+class MismatchArgumentException(Exception):
+ pass
diff --git a/tests/resources/example_robot_output.xml b/tests/resources/example_robot_output.xml
index e241ba2..78079a4 100644
--- a/tests/resources/example_robot_output.xml
+++ b/tests/resources/example_robot_output.xml
@@ -258,6 +258,56 @@
+
+
+Logs the given message with the given level.
+
+My Dummy Handler Setup Here 1
+
+My Dummy Handler Setup Here 1
+
+
+
+Logs the given message with the given level.
+
+My Dummy Handler Setup Here 2
+
+My Dummy Handler Setup Here 2
+
+
+
+Run My Dummy Handler tool specified with ``command``.
+
+${RESOURCES}/my_dummy_handler.xml
+echo
+MY_DUMMY_HANDLER_TEST_STRING
+
+MY_DUMMY_HANDLER_TEST_STRING
+
+Result file: /Users/tkairi/Coding/oxygen/tests/atest/../resources/my_dummy_handler.xml
+
+
+
+Logs the given message with the given level.
+
+My Dummy Handler Teardown Here 1
+
+My Dummy Handler Teardown Here 1
+
+
+
+Logs the given message with the given level.
+
+My Dummy Handler Teardown Here 2
+
+My Dummy Handler Teardown Here 2
+
+
+
+MY_DUMMY_HANDLER_ROBOT_TAG
+
+
+
@@ -272,6 +322,7 @@
JUNIT_ROBOT_TAG
NO_OXYGEN_HERE
ZAP_ROBOT_TAG
+MY_DUMMY_HANDLER_ROBOT_TAG
Atest
diff --git a/tests/resources/my_dummy_handlers/__init__.py b/tests/resources/my_dummy_handlers/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/resources/my_dummy_handlers/dummy_handler_default_params.py b/tests/resources/my_dummy_handlers/dummy_handler_default_params.py
new file mode 100644
index 0000000..9ee23f0
--- /dev/null
+++ b/tests/resources/my_dummy_handlers/dummy_handler_default_params.py
@@ -0,0 +1,17 @@
+from oxygen import BaseHandler
+
+
+class MyDummyHandler(BaseHandler):
+ '''
+ A test handler that throws mismatch argument exception if single argument
+ is passed with multiple accepted
+ '''
+
+ def run_my_dummy_handler(self, result_file):
+ return result_file
+
+ def parse_results(self, result_file, foo='foo'):
+ return {
+ 'name': result_file,
+ 'foo': foo
+ }
diff --git a/tests/resources/my_dummy_handlers/dummy_handler_multiple_args.py b/tests/resources/my_dummy_handlers/dummy_handler_multiple_args.py
new file mode 100644
index 0000000..e34c503
--- /dev/null
+++ b/tests/resources/my_dummy_handlers/dummy_handler_multiple_args.py
@@ -0,0 +1,17 @@
+from oxygen import BaseHandler
+
+
+class MyDummyHandler(BaseHandler):
+ '''
+ A test handler for unfolding parse_results arguments
+ if it has multiple parameters
+ '''
+
+ def run_my_dummy_handler(self, result_file):
+ return result_file, 'foo'
+
+ def parse_results(self, result_file, foo):
+ return {
+ 'name': result_file,
+ 'foo': foo
+ }
diff --git a/tests/resources/my_dummy_handlers/dummy_handler_multiple_args_too_few.py b/tests/resources/my_dummy_handlers/dummy_handler_multiple_args_too_few.py
new file mode 100644
index 0000000..ec15650
--- /dev/null
+++ b/tests/resources/my_dummy_handlers/dummy_handler_multiple_args_too_few.py
@@ -0,0 +1,18 @@
+from oxygen import BaseHandler
+
+
+class MyDummyHandler(BaseHandler):
+ '''
+ A test handler that throws mismatch argument exception because
+ parse_results expects too many arguments
+ '''
+
+ def run_my_dummy_handler(self, result_file):
+ return result_file, 'foo'
+
+ def parse_results(self, result_file, foo, bar):
+ return {
+ 'name': result_file,
+ 'foo': foo,
+ 'bar': bar
+ }
diff --git a/tests/resources/my_dummy_handlers/dummy_handler_single_arg.py b/tests/resources/my_dummy_handlers/dummy_handler_single_arg.py
new file mode 100644
index 0000000..ad1616a
--- /dev/null
+++ b/tests/resources/my_dummy_handlers/dummy_handler_single_arg.py
@@ -0,0 +1,15 @@
+from oxygen import BaseHandler
+
+
+class MyDummyHandler(BaseHandler):
+ '''
+ A test handler for passing tuple if parse_results accepts one parameter
+ '''
+
+ def run_my_dummy_handler(self, result_file):
+ return result_file, 'foo'
+
+ def parse_results(self, result_file):
+ return {
+ 'name': result_file
+ }
diff --git a/tests/utest/helpers.py b/tests/utest/helpers.py
index e6725a4..0174a41 100644
--- a/tests/utest/helpers.py
+++ b/tests/utest/helpers.py
@@ -25,6 +25,10 @@
tags: ZAP
accepted_risk_level: 2
required_confidence_level: 1
+oxygen.my_dummy_handler:
+ handler: MyDummyHandler
+ keyword: run_my_dummy_handler
+ tags: MY_DUMMY_HANDLER
'''
RESOURCES_PATH = Path.cwd() / 'tests' / 'resources'
diff --git a/tests/utest/my_dummy_handler/__init__.py b/tests/utest/my_dummy_handler/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/utest/my_dummy_handler/test_basic_functionality.py b/tests/utest/my_dummy_handler/test_basic_functionality.py
new file mode 100644
index 0000000..f863fd5
--- /dev/null
+++ b/tests/utest/my_dummy_handler/test_basic_functionality.py
@@ -0,0 +1,150 @@
+import sys
+from unittest import TestCase
+from oxygen.errors import MismatchArgumentException
+from ..helpers import RESOURCES_PATH, get_config, example_robot_output
+
+sys.path.append(str(RESOURCES_PATH / 'my_dummy_handlers'))
+
+from dummy_handler_single_arg import (
+ MyDummyHandler as DummyHandlerSingleArg,
+)
+from dummy_handler_multiple_args import (
+ MyDummyHandler as DummyHandlerMultipleArgs,
+)
+from dummy_handler_multiple_args_too_few import (
+ MyDummyHandler as DummyHandlerMultipleArgsTooFew,
+)
+from dummy_handler_default_params import (
+ MyDummyHandler as DummyHandlerDefaultParams,
+)
+
+
+class DummyHandlerSingleArgTests(TestCase):
+ '''
+ A test for passing tuple if parse_results accepts one parameter
+ '''
+
+ def setUp(self):
+ self.handler = DummyHandlerSingleArg(
+ get_config()['oxygen.my_dummy_handler']
+ )
+
+ def test_run_my_dummy_handler(self):
+ return_value = self.handler.run_my_dummy_handler('/some/path/to.ext')
+ self.assertTupleEqual(return_value, ('/some/path/to.ext', 'foo'))
+
+ def test_parse_results(self):
+ fake_test = example_robot_output().suite.suites[0].tests[6]
+ expected_data = {'Atest.Test.My Fifth Test': '/some/path/to.ext'}
+
+ self.handler.check_for_keyword(fake_test, expected_data)
+
+ self.assertEqual(self.handler.run_time_data, '/some/path/to.ext')
+
+
+class DummyHandlerMultipleArgsTests(TestCase):
+ '''
+ A test for unfolding parse_results arguments
+ if it has multiple parameters
+ '''
+
+ def setUp(self):
+ self.handler = DummyHandlerMultipleArgs(
+ get_config()['oxygen.my_dummy_handler']
+ )
+
+ def test_parse_results(self):
+ fake_test = example_robot_output().suite.suites[0].tests[6]
+ expected_data = {
+ 'Atest.Test.My Fifth Test': ('/some/path/to.ext', 'foo')
+ }
+
+ self.handler.check_for_keyword(fake_test, expected_data)
+
+ self.assertEqual(
+ self.handler.run_time_data, ('/some/path/to.ext', 'foo')
+ )
+
+
+class DummyHandlerMultipleArgsTooFewTests(TestCase):
+ '''
+ A test for testing if it throws mismatch argument exception because
+ parse_results expects too many arguments
+ '''
+
+ def setUp(self):
+ self.handler = DummyHandlerMultipleArgsTooFew(
+ get_config()['oxygen.my_dummy_handler']
+ )
+
+ def test_parse_results(self):
+ fake_test = example_robot_output().suite.suites[0].tests[6]
+ expected_data = {
+ 'Atest.Test.My Fifth Test': ('/some/path/to.ext', 'foo')
+ }
+
+ self.assertRaises(
+ MismatchArgumentException,
+ self.handler.check_for_keyword,
+ fake_test,
+ expected_data,
+ )
+
+
+class DummyHandlerMultipleArgsSingleTests(TestCase):
+ '''
+ A test for testing if it throws mismatch argument exception because
+ parse_results expects multiple arguments but we do not pass multiple
+ '''
+
+ def setUp(self):
+ self.handler = DummyHandlerMultipleArgsTooFew(
+ get_config()['oxygen.my_dummy_handler']
+ )
+
+ def test_parse_results(self):
+ fake_test = example_robot_output().suite.suites[0].tests[6]
+ expected_data = {'Atest.Test.My Fifth Test': 'some/path/to.ext'}
+
+ self.assertRaises(
+ MismatchArgumentException,
+ self.handler.check_for_keyword,
+ fake_test,
+ expected_data,
+ )
+
+
+class DummyHandlerDefaultParamsTests(TestCase):
+ '''
+ A test for testing arguments with defaults
+ '''
+
+ def setUp(self):
+ self.handler = DummyHandlerDefaultParams(
+ get_config()['oxygen.my_dummy_handler']
+ )
+
+ def test_parse_results_with_one(self):
+ fake_test = example_robot_output().suite.suites[0].tests[6]
+ expected_data = {'Atest.Test.My Fifth Test': 'some/path/to.ext'}
+ self.handler.check_for_keyword(fake_test, expected_data)
+ self.assertEqual(self.handler.run_time_data, 'some/path/to.ext')
+
+ def test_parse_results_with_multiple(self):
+ fake_test = example_robot_output().suite.suites[0].tests[6]
+ expected_data = {
+ 'Atest.Test.My Fifth Test': ('some/path/to.ext', 'foo')}
+ self.handler.check_for_keyword(fake_test, expected_data)
+ self.assertTupleEqual(
+ self.handler.run_time_data, ('some/path/to.ext', 'foo'))
+
+ def test_parse_results_with_too_many(self):
+ fake_test = example_robot_output().suite.suites[0].tests[6]
+ expected_data = {
+ 'Atest.Test.My Fifth Test': ('some/path/to.ext', 'foo', 'bar')}
+ self.assertRaises(
+ MismatchArgumentException,
+ self.handler.check_for_keyword,
+ fake_test,
+ expected_data,
+ )