diff --git a/main.py b/main.py index 9175192..14bd4a4 100644 --- a/main.py +++ b/main.py @@ -3,14 +3,21 @@ import argparse from src.lib import get_api_envs -from src.utils import get_common_terms +from src.utils import get_common_terms, apply_regex def create_parser(): parser = argparse.ArgumentParser(description='Quizlet Utils') - commands = parser.add_subparsers(title="Commands", dest="command") - commands.add_parser("common", help="Find duplicate terms across all sets") + commands = parser.add_subparsers(title='Commands', dest='command') commands.required = True + + commands.add_parser('common', help='Find duplicate terms across all sets') + + apply = commands.add_parser('apply', help='Apply regex replace to set') + apply.add_argument('pattern', type=str, help='Pattern to search for') + apply.add_argument('repl', type=str, help='Replacement for pattern') + apply.add_argument('set_name', type=str, help='Word set to apply to') + return parser @@ -20,6 +27,8 @@ def main(): api_envs = get_api_envs() if args.command == 'common': get_common_terms(*api_envs) + elif args.command == 'apply': + apply_regex(args.pattern, args.repl, args.set_name, *api_envs) if __name__ == '__main__': diff --git a/src/utils.py b/src/utils.py index d8e0296..fdef752 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,4 +1,5 @@ """User-available utilities.""" +# ToDo: rename the module from itertools import combinations @@ -19,3 +20,8 @@ def get_common_terms(*api_envs): common_terms.append( (word_set_1, word_set_2, word_set_1.has_common(word_set_2))) return common_terms + + +def apply_regex(pattern, repl, set_name, *api_envs): + """Apply regex replace to all terms in word set.""" + raise NotImplementedError # ToDo: complete the utility diff --git a/tests/src/test_lib.py b/tests/src/test_lib.py index 322b1c5..af57a01 100644 --- a/tests/src/test_lib.py +++ b/tests/src/test_lib.py @@ -1,23 +1,8 @@ -import os import unittest -from functools import wraps from unittest import mock from src.lib import api_call, get_api_envs - - -def mock_envs(**envs): - """Mock environment variables for test.""" - - def decorator(func): - @wraps(func) - def wrapper(*args, **kwargs): - with mock.patch.dict(os.environ, envs, clear=True): - func(*args, **kwargs) - - return wrapper - - return decorator +from tests.utils import mock_envs class TestGetApiEnvs(unittest.TestCase): diff --git a/tests/src/test_utils.py b/tests/src/test_utils.py index e69de29..fe9909b 100644 --- a/tests/src/test_utils.py +++ b/tests/src/test_utils.py @@ -0,0 +1 @@ +# ToDo: add tests diff --git a/tests/test_main.py b/tests/test_main.py index 0817884..5b99553 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -2,6 +2,7 @@ from unittest import mock from main import create_parser, main +from tests.src.test_lib import mock_envs class TestCreateParser(unittest.TestCase): @@ -20,11 +21,30 @@ def test_common_command(self): args = self.parser.parse_args(['common']) self.assertEqual(args.command, 'common') + def test_apply_command_without_args(self): + with self.assertRaises(SystemExit): + self.parser.parse_args(['apply']) + + def test_apply_command_with_all_args(self): + args = self.parser.parse_args(['apply', 'pattern', 'repl', 'set_name']) + self.assertEqual(args.command, 'apply') + self.assertEqual(args.pattern, 'pattern') + self.assertEqual(args.repl, 'repl') + self.assertEqual(args.set_name, 'set_name') + +@mock_envs(CLIENT_ID='client_id', USER_ID='user_id') class TestMain(unittest.TestCase): @mock.patch('main.get_common_terms') - @mock.patch('main.get_api_envs', mock.Mock(return_value=[])) @mock.patch('sys.argv', ['', 'common']) def test_common(self, mock_get_common_terms): main() mock_get_common_terms.assert_called_once() + + @mock.patch('main.apply_regex') + @mock.patch('sys.argv', ['', 'apply', 'pattern', 'repl', 'set_name']) + def test_apply(self, mock_apply_regex): + main() + mock_apply_regex.assert_called_once() + +# ToDo: add decorator for mocking system arguments diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 0000000..c179d06 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,30 @@ +"""Utilities for tests.""" + +import inspect +from functools import wraps +from unittest import mock + + +def mock_envs(**envs): + """Mock environment variables for test. + + Can be applied to: + - any function + - test class - all test methods (starts with "test_*" will be decorated) + """ + + def decorator(obj): + @wraps(obj) + def wrapper(*args, **kwargs): + with mock.patch.dict('os.environ', envs, clear=True): + obj(*args, **kwargs) + + if inspect.isclass(obj): + for name, method in inspect.getmembers(obj, inspect.isfunction): + if name.startswith('test_'): + setattr(obj, name, decorator(method)) + return obj + else: + return wrapper + + return decorator