diff --git a/tests/cli/test_convert.py b/tests/cli/test_convert.py new file mode 100644 index 000000000..c77a0b3a0 --- /dev/null +++ b/tests/cli/test_convert.py @@ -0,0 +1,72 @@ +""" +Tests for the CLI convert functionality. + +.. raw:: html + +""" + +import unittest +from unittest.mock import patch +from pathlib import Path +from scribe_data.cli.convert import export_json, convert_to_sqlite + +class TestConvert(unittest.TestCase): + + @patch('scribe_data.cli.convert.Path') + @patch('scribe_data.cli.convert.data_to_sqlite') + @patch('shutil.copy') + def test_convert_to_sqlite(self, mock_shutil_copy, mock_data_to_sqlite, mock_path): + mock_path.return_value.exists.return_value = True + + convert_to_sqlite('english', 'nouns', '/output', True) + + mock_data_to_sqlite.assert_called_with(['english'], ['nouns']) + mock_shutil_copy.assert_called() + + @patch('scribe_data.cli.convert.Path') + @patch('scribe_data.cli.convert.data_to_sqlite') + def test_convert_to_sqlite_no_output_dir(self, mock_data_to_sqlite, mock_path): + convert_to_sqlite('english', 'nouns', None, True) + + mock_data_to_sqlite.assert_called_with(['english'], ['nouns']) + mock_path.assert_not_called() + + @patch('scribe_data.cli.convert.Path') + @patch('scribe_data.cli.convert.data_to_sqlite') + @patch('scribe_data.cli.convert.get_language_iso') + @patch('shutil.copy') + def test_convert_to_sqlite_with_language_iso(self, mock_copy, mock_get_language_iso, mock_data_to_sqlite, mock_path): + mock_get_language_iso.return_value = "en" + mock_path.return_value.exists.return_value = True + + convert_to_sqlite("English", "data_type", "/output", True) + + mock_data_to_sqlite.assert_called_with(["English"], ["data_type"]) + mock_copy.assert_called() + + @patch('scribe_data.cli.convert.language_map') + def test_export_json_invalid_language(self, mock_language_map): + mock_language_map.get.return_value = None + + with self.assertRaises(ValueError): + export_json("invalid", "data_type", Path("/output"), True) + + + def test_convert_to_sqlite_no_language(self): + with self.assertRaises(ValueError): + convert_to_sqlite(None, "data_type", "/output", True) diff --git a/tests/cli/test_get.py b/tests/cli/test_get.py new file mode 100644 index 000000000..4bd09b5bd --- /dev/null +++ b/tests/cli/test_get.py @@ -0,0 +1,45 @@ +""" +Tests for the CLI get functionality. + +.. raw:: html + +""" + +import unittest +from unittest.mock import patch, call +from scribe_data.cli.get import get_data + +class TestCLIGetCommand(unittest.TestCase): + @patch('scribe_data.cli.get.query_data') + @patch('scribe_data.cli.get.export_json') + @patch('scribe_data.cli.get.convert_to_csv_or_tsv') + @patch('os.system') + def test_get_command(self, mock_system, mock_convert, mock_export_json, mock_query_data): + expected_calls = [ + call(['English'], ['nouns']), + call(['English'], ['nouns']), + call() + ] + + # Execute the test + get_data(language='English', data_type='nouns', output_dir='outputs', output_type='json') + get_data(language='English', data_type='nouns', output_dir='outputs', output_type='csv') + get_data(all=True) + + # Validate the calls + mock_query_data.assert_has_calls(expected_calls, any_order=True) diff --git a/tests/cli/test_list.py b/tests/cli/test_list.py new file mode 100644 index 000000000..8fa2f5c97 --- /dev/null +++ b/tests/cli/test_list.py @@ -0,0 +1,172 @@ +""" +Tests for the list file functions. + +.. raw:: html + +""" + +import unittest +from unittest.mock import patch, call +from scribe_data.cli.list import ( + list_languages, + list_data_types, + list_all, + list_languages_for_data_type, + list_wrapper, +) +from scribe_data.cli.main import main + +class TestListFunctions(unittest.TestCase): + @patch("builtins.print") + def test_list_languages(self, mock_print): + list_languages() + expected_calls = [ + call(), + call('Language ISO QID '), + call('-----------------------'), + call('English en Q1860 '), + call('French fr Q150 '), + call('German de Q188 '), + call('Italian it Q652 '), + call('Portuguese pt Q5146 '), + call('Russian ru Q7737 '), + call('Spanish es Q1321 '), + call('Swedish sv Q9027 '), + call('-----------------------'), + call(), + ] + mock_print.assert_has_calls(expected_calls) + + @patch("builtins.print") + def test_list_data_types_all_languages(self, mock_print): + list_data_types() + expected_calls = [ + call(), + call('Available data types: All languages'), + call('-----------------------------------'), + call('emoji-keywords'), + call('nouns'), + call('prepositions'), + call('translations'), + call('verbs'), + call('-----------------------------------'), + call(), + ] + mock_print.assert_has_calls(expected_calls) + + @patch("builtins.print") + def test_list_data_types_specific_language(self, mock_print): + list_data_types("English") + expected_calls = [ + call(), + call('Available data types: English'), + call('-----------------------------'), + call('emoji-keywords'), + call('nouns'), + call('translations'), + call('verbs'), + call('-----------------------------'), + call(), + ] + mock_print.assert_has_calls(expected_calls) + + def test_list_data_types_invalid_language(self): + with self.assertRaises(ValueError): + list_data_types("InvalidLanguage") + + def test_list_data_types_no_data_types(self): + with self.assertRaises(ValueError): + list_data_types("Klingon") + + @patch("scribe_data.cli.list.list_languages") + @patch("scribe_data.cli.list.list_data_types") + def test_list_all(self, mock_list_data_types, mock_list_languages): + list_all() + mock_list_languages.assert_called_once() + mock_list_data_types.assert_called_once() + + @patch("scribe_data.cli.list.list_all") + def test_list_wrapper_all(self, mock_list_all): + list_wrapper(all_bool=True) + mock_list_all.assert_called_once() + + @patch("scribe_data.cli.list.list_languages") + def test_list_wrapper_languages(self, mock_list_languages): + list_wrapper(language=True) + mock_list_languages.assert_called_once() + + @patch("scribe_data.cli.list.list_data_types") + def test_list_wrapper_data_types(self, mock_list_data_types): + list_wrapper(data_type=True) + mock_list_data_types.assert_called_once() + + @patch("builtins.print") + def test_list_wrapper_language_and_data_type(self, mock_print): + list_wrapper(language=True, data_type=True) + mock_print.assert_called_with("Please specify either a language or a data type.") + + @patch("scribe_data.cli.list.list_languages_for_data_type") + def test_list_wrapper_languages_for_data_type(self, mock_list_languages_for_data_type): + list_wrapper(language=True, data_type="example_data_type") + mock_list_languages_for_data_type.assert_called_with("example_data_type") + + @patch("scribe_data.cli.list.list_data_types") + def test_list_wrapper_data_types_for_language(self, mock_list_data_types): + list_wrapper(language="English", data_type=True) + mock_list_data_types.assert_called_with("English") + + @patch("builtins.print") + def test_list_languages_for_data_type_valid(self, mock_print): + list_languages_for_data_type("nouns") + expected_calls = [ + call(), + call('Available languages: nouns'), + call('--------------------------'), + call('English'), + call('French'), + call('German'), + call('Italian'), + call('Portuguese'), + call('Russian'), + call('Spanish'), + call('Swedish'), + call('--------------------------'), + call(), + ] + mock_print.assert_has_calls(expected_calls) + + @patch('scribe_data.cli.list.list_languages') + def test_list_languages_command(self, mock_list_languages): + test_args = ['main.py', 'list', '--language'] + with patch('sys.argv', test_args): + main() + mock_list_languages.assert_called_once() + + @patch('scribe_data.cli.list.list_data_types') + def test_list_data_types_command(self, mock_list_data_types): + test_args = ['main.py', 'list', '--data-type'] + with patch('sys.argv', test_args): + main() + mock_list_data_types.assert_called_once() + + @patch('scribe_data.cli.list.list_all') + def test_list_all_command(self, mock_list_all): + test_args = ['main.py', 'list', '--all'] + with patch('sys.argv', test_args): + main() + mock_list_all.assert_called_once() diff --git a/tests/cli/test_total.py b/tests/cli/test_total.py new file mode 100644 index 000000000..ee7cdc649 --- /dev/null +++ b/tests/cli/test_total.py @@ -0,0 +1,127 @@ +""" +Tests for the CLI total functionality. + +.. raw:: html + +""" + +import unittest +from unittest.mock import patch, MagicMock, call +from scribe_data.cli.total import get_total_lexemes + +class TestTotalLexemes(unittest.TestCase): + @patch('scribe_data.cli.total.get_qid_by_input') + @patch('scribe_data.cli.total.sparql.query') + def test_get_total_lexemes_valid(self, mock_query, mock_get_qid): + mock_get_qid.side_effect = lambda x: {'english': 'Q1860', 'nouns': 'Q1084'}.get(x.lower(), None) + mock_results = MagicMock() + mock_results.convert.return_value = { + "results": { + "bindings": [ + {"total": {"value": "42"}} + ] + } + } + mock_query.return_value = mock_results + + with patch('builtins.print') as mock_print: + get_total_lexemes('English', 'nouns') + + mock_print.assert_called_once_with('Language: English\nData type: nouns\nTotal number of lexemes: 42') + + @patch('scribe_data.cli.total.get_qid_by_input') + @patch('scribe_data.cli.total.sparql.query') + def test_get_total_lexemes_no_results(self, mock_query, mock_get_qid): + mock_get_qid.side_effect = lambda x: {'english': 'Q1860', 'nouns': 'Q1084'}.get(x.lower(), None) + mock_results = MagicMock() + mock_results.convert.return_value = { + "results": { + "bindings": [] + } + } + mock_query.return_value = mock_results + + with patch('builtins.print') as mock_print: + get_total_lexemes('English', 'nouns') + + mock_print.assert_called_once_with('Total number of lexemes: Not found') + + @patch('scribe_data.cli.total.get_qid_by_input') + @patch('scribe_data.cli.total.sparql.query') + def test_get_total_lexemes_invalid_language(self, mock_query, mock_get_qid): + mock_get_qid.side_effect = lambda x: None + mock_query.return_value = MagicMock() + + with patch('builtins.print') as mock_print: + get_total_lexemes('InvalidLanguage', 'nouns') + + mock_print.assert_called_once_with('Total number of lexemes: Not found') + + @patch('scribe_data.cli.total.get_qid_by_input') + @patch('scribe_data.cli.total.sparql.query') + def test_get_total_lexemes_empty_and_none_inputs(self, mock_query, mock_get_qid): + mock_get_qid.return_value = None + mock_query.return_value = MagicMock() + + # Call the function with empty and None inputs + with patch('builtins.print') as mock_print: + get_total_lexemes('', 'nouns') + get_total_lexemes(None, 'verbs') + + expected_calls = [ + call('Total number of lexemes: Not found'), + call('Total number of lexemes: Not found') + ] + mock_print.assert_has_calls(expected_calls, any_order=True) + + @patch('scribe_data.cli.total.get_qid_by_input') + @patch('scribe_data.cli.total.sparql.query') + def test_get_total_lexemes_nonexistent_language(self, mock_query, mock_get_qid): + mock_get_qid.return_value = None + mock_query.return_value = MagicMock() + + with patch('builtins.print') as mock_print: + get_total_lexemes('Martian', 'nouns') + + mock_print.assert_called_once_with('Total number of lexemes: Not found') + + @patch('scribe_data.cli.total.get_qid_by_input') + @patch('scribe_data.cli.total.sparql.query') + def test_get_total_lexemes_various_data_types(self, mock_query, mock_get_qid): + mock_get_qid.side_effect = lambda x: {'english': 'Q1860', 'verbs': 'Q24905', 'nouns': 'Q1084'}.get(x.lower(), None) + mock_results = MagicMock() + mock_results.convert.return_value = { + "results": { + "bindings": [ + {"total": {"value": "30"}} + ] + } + } + + mock_query.return_value = mock_results + + # Call the function with different data types + with patch('builtins.print') as mock_print: + get_total_lexemes('English', 'verbs') + get_total_lexemes('English', 'nouns') + + expected_calls = [ + call('Language: English\nData type: verbs\nTotal number of lexemes: 30'), + call('Language: English\nData type: nouns\nTotal number of lexemes: 30') + ] + mock_print.assert_has_calls(expected_calls)