Skip to content

Commit ac3382d

Browse files
committed
IMPROVEMENT: increased test coverage
1 parent 9fff6b1 commit ac3382d

File tree

3 files changed

+124
-6
lines changed

3 files changed

+124
-6
lines changed

MethodicConfigurator/annotate_params.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,8 +673,13 @@ def get_xml_url(vehicle_type: str, firmware_version: str) -> str:
673673
'Heli': 'versioned/Heli/stable-',
674674
'SITL': 'versioned/SITL/stable-'
675675
}
676+
try:
677+
vehicle_subdir = vehicle_parm_subdir[vehicle_type] + firmware_version
678+
except KeyError as e:
679+
raise ValueError(f"Vehicle type '{vehicle_type}' is not supported.") from e
680+
676681
if firmware_version:
677-
xml_url = BASE_URL + vehicle_parm_subdir[vehicle_type] + firmware_version + "/"
682+
xml_url = BASE_URL + vehicle_subdir + "/"
678683
else:
679684
xml_url = BASE_URL + vehicle_type + "/"
680685
return xml_url

unittests/annotate_params_test.py

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,20 @@
1111
# pylint: skip-file
1212

1313
import tempfile
14-
from unittest.mock import patch, mock_open
14+
from unittest.mock import patch, mock_open, Mock
1515
import os
1616
import unittest
1717
import requests
1818
import mock
19+
import argparse
1920

2021
from xml.etree import ElementTree as ET # no parsing, just data-structure manipulation
2122
from defusedxml import ElementTree as DET # just parsing, no data-structure manipulation
2223

24+
from MethodicConfigurator.annotate_params import arg_parser
25+
from MethodicConfigurator.annotate_params import main
2326
from MethodicConfigurator.annotate_params import get_xml_data
27+
from MethodicConfigurator.annotate_params import get_xml_url
2428
from MethodicConfigurator.annotate_params import remove_prefix
2529
from MethodicConfigurator.annotate_params import split_into_lines
2630
from MethodicConfigurator.annotate_params import create_doc_dict
@@ -79,7 +83,7 @@ def test_get_xml_data_local_file(self, mock_load_param, mock_isfile, mock_open):
7983
self.assertIsInstance(result, ET.Element)
8084

8185
# Assert that the file was opened correctly
82-
mock_open.assert_called_once_with('./test.xml', 'r', encoding='utf-8')
86+
mock_open.assert_called_once_with(os.path.join(".", "test.xml"), 'r', encoding='utf-8')
8387

8488
@patch('requests.get')
8589
def test_get_xml_data_remote_file(self, mock_get):
@@ -552,5 +556,99 @@ def test_empty_parameter_file(self):
552556
self.assertEqual(updated_content, "")
553557

554558

559+
class AnnotateParamsTest(unittest.TestCase):
560+
561+
@patch('argparse.ArgumentParser.parse_args')
562+
def test_arg_parser_valid_arguments(self, mock_parse_args):
563+
test_args = ['--vehicle-type', 'ArduCopter', '--sort', 'none', '--target', 'parameters']
564+
mock_parse_args.return_value = argparse.Namespace(
565+
vehicle_type='ArduCopter',
566+
sort='none',
567+
target='parameters',
568+
verbose=False,
569+
max_line_length=100,
570+
)
571+
with patch('sys.argv', test_args):
572+
args = arg_parser()
573+
self.assertEqual(args.vehicle_type, 'ArduCopter')
574+
self.assertEqual(args.sort, 'none')
575+
self.assertEqual(args.target, 'parameters')
576+
self.assertEqual(args.verbose, False)
577+
self.assertEqual(args.max_line_length, 100)
578+
579+
def test_arg_parser_invalid_vehicle_type(self):
580+
test_args = ['--vehicle-type', 'InvalidType', '--sort', 'none', '--target', 'parameters']
581+
with patch('sys.argv', test_args):
582+
with self.assertRaises(SystemExit):
583+
arg_parser()
584+
585+
def test_arg_parser_invalid_sort_option(self):
586+
test_args = ['--vehicle-type', 'ArduCopter', '--sort', 'invalid', '--target', 'parameters']
587+
with patch('sys.argv', test_args):
588+
with self.assertRaises(SystemExit):
589+
arg_parser()
590+
591+
def test_arg_parser_invalid_target_option(self):
592+
test_args = ['--vehicle-type', 'ArduCopter', '--sort', 'none', '--target', 'invalid']
593+
with patch('sys.argv', test_args):
594+
with self.assertRaises(SystemExit):
595+
arg_parser()
596+
597+
598+
class TestAnnotateParamsExceptionHandling(unittest.TestCase):
599+
600+
@patch('annotate_params.arg_parser')
601+
@patch('annotate_params.get_xml_url')
602+
@patch('annotate_params.get_xml_dir')
603+
@patch('annotate_params.parse_parameter_metadata')
604+
@patch('annotate_params.update_parameter_documentation')
605+
@patch('builtins.open', new_callable=mock_open)
606+
def test_main_ioerror(
607+
self, mock_file, mock_update, mock_parse_metadata, mock_get_xml_dir, mock_get_xml_url, mock_arg_parser
608+
):
609+
mock_arg_parser.return_value = Mock(
610+
vehicle_type='ArduCopter',
611+
target='.',
612+
sort='none',
613+
delete_documentation_annotations=False,
614+
verbose=False
615+
)
616+
mock_file.side_effect = IOError("Mocked IO Error")
617+
618+
with self.assertRaises(SystemExit) as cm:
619+
main()
620+
621+
self.assertEqual(cm.exception.code, 2)
622+
623+
@patch('annotate_params.arg_parser')
624+
@patch('annotate_params.get_xml_url')
625+
@patch('annotate_params.get_xml_dir')
626+
@patch('annotate_params.parse_parameter_metadata')
627+
@patch('annotate_params.update_parameter_documentation')
628+
@patch('builtins.open', new_callable=mock_open)
629+
def test_main_oserror(
630+
self, mock_file, mock_update, mock_parse_metadata, mock_get_xml_dir, mock_get_xml_url, mock_arg_parser
631+
):
632+
mock_arg_parser.return_value = Mock(
633+
vehicle_type='ArduCopter',
634+
target='.',
635+
sort='none',
636+
delete_documentation_annotations=False,
637+
verbose=False
638+
)
639+
mock_file.side_effect = OSError("Mocked OS Error")
640+
641+
with self.assertRaises(SystemExit) as cm:
642+
main()
643+
644+
self.assertEqual(cm.exception.code, 2)
645+
646+
@patch('annotate_params.get_xml_url')
647+
def test_get_xml_url_exception(self, mock_get_xml_url):
648+
mock_get_xml_url.side_effect = ValueError("Mocked Value Error")
649+
with self.assertRaises(ValueError):
650+
get_xml_url('NonExistingVehicle', '4.0')
651+
652+
555653
if __name__ == '__main__':
556654
unittest.main()

unittests/annotate_params_test.sh

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,23 @@
22
#
33
# SPDX-FileCopyrightText: 2024 Amilcar do Carmo Lucas <[email protected]>
44
#
5-
#SPDX-License-Identifier: GPL-3.0-or-later
5+
# SPDX-License-Identifier: GPL-3.0-or-later
66

7-
PYTHONPATH=../MethodicConfigurator python3 -m coverage run -m unittest annotate_params_test.py
8-
python3 -m coverage html
7+
REQUIRED_PKGS=("coverage" "mock" "defusedxml")
8+
9+
is_installed() {
10+
pip show "$1" > /dev/null 2>&1
11+
}
12+
13+
for pkg in "${REQUIRED_PKGS[@]}"; do
14+
if ! is_installed "$pkg"; then
15+
echo "Installing $pkg..."
16+
pip install "$pkg"
17+
else
18+
echo "$pkg is already installed."
19+
fi
20+
done
21+
22+
PYTHONPATH=../MethodicConfigurator python -m coverage run -m unittest annotate_params_test.py
23+
python -m coverage html
924
firefox htmlcov/annotate_params_py.html

0 commit comments

Comments
 (0)