| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | # -*- coding: utf-8; -*- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 23:32:11 -05:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | from unittest import TestCase | 
					
						
							|  |  |  | from unittest.mock import patch, MagicMock | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 23:32:11 -05:00
										 |  |  | import pytest | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-15 20:18:54 -05:00
										 |  |  | from wuttjamaican import util as mod | 
					
						
							| 
									
										
										
										
											2024-08-24 17:19:50 -05:00
										 |  |  | from wuttjamaican.progress import ProgressBase | 
					
						
							| 
									
										
										
										
											2024-08-15 20:18:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  | class A: | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class B(A): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class C(B): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-15 20:18:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TestGetClassHierarchy(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         classes = mod.get_class_hierarchy(A) | 
					
						
							|  |  |  |         self.assertEqual(classes, [A]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         classes = mod.get_class_hierarchy(B) | 
					
						
							|  |  |  |         self.assertEqual(classes, [A, B]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         classes = mod.get_class_hierarchy(C) | 
					
						
							|  |  |  |         self.assertEqual(classes, [A, B, C]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         classes = mod.get_class_hierarchy(C, topfirst=False) | 
					
						
							|  |  |  |         self.assertEqual(classes, [C, B, A]) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestLoadEntryPoints(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_empty(self): | 
					
						
							|  |  |  |         # empty set returned for unknown group | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         result = mod.load_entry_points("this_should_never_exist!!!!!!") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertEqual(result, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							|  |  |  |         # load some entry points which should "always" be present, | 
					
						
							|  |  |  |         # even in a testing environment.  basic sanity check | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         result = mod.load_entry_points("console_scripts", ignore_errors=True) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertTrue(len(result) >= 1) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertIn("pip", result) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-19 14:22:25 -06:00
										 |  |  |     def test_basic_pre_python_3_10(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # the goal here is to get coverage for code which would only | 
					
						
							|  |  |  |         # run on python 3,9 and older, but we only need that coverage | 
					
						
							|  |  |  |         # if we are currently testing python 3.10+ | 
					
						
							|  |  |  |         if sys.version_info.major == 3 and sys.version_info.minor < 10: | 
					
						
							|  |  |  |             pytest.skip("this test is not relevant before python 3.10") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         import importlib.metadata | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-19 14:22:25 -06:00
										 |  |  |         real_entry_points = importlib.metadata.entry_points() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class FakeEntryPoints(dict): | 
					
						
							|  |  |  |             def get(self, group, default): | 
					
						
							|  |  |  |                 return real_entry_points.select(group=group) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         importlib = MagicMock() | 
					
						
							|  |  |  |         importlib.metadata.entry_points.return_value = FakeEntryPoints() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.dict("sys.modules", **{"importlib": importlib}): | 
					
						
							| 
									
										
										
										
											2023-11-19 14:22:25 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # load some entry points which should "always" be present, | 
					
						
							|  |  |  |             # even in a testing environment.  basic sanity check | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             result = mod.load_entry_points("console_scripts", ignore_errors=True) | 
					
						
							| 
									
										
										
										
											2023-11-19 14:22:25 -06:00
										 |  |  |             self.assertTrue(len(result) >= 1) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.assertIn("pytest", result) | 
					
						
							| 
									
										
										
										
											2024-06-14 17:27:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basic_pre_python_3_8(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # the goal here is to get coverage for code which would only | 
					
						
							|  |  |  |         # run on python 3.7 and older, but we only need that coverage | 
					
						
							|  |  |  |         # if we are currently testing python 3.8+ | 
					
						
							|  |  |  |         if sys.version_info.major == 3 and sys.version_info.minor < 8: | 
					
						
							|  |  |  |             pytest.skip("this test is not relevant before python 3.8") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         from importlib.metadata import entry_points | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-14 17:27:22 -05:00
										 |  |  |         real_entry_points = entry_points() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class FakeEntryPoints(dict): | 
					
						
							|  |  |  |             def get(self, group, default): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |                 if hasattr(real_entry_points, "select"): | 
					
						
							| 
									
										
										
										
											2024-06-14 17:27:22 -05:00
										 |  |  |                     return real_entry_points.select(group=group) | 
					
						
							|  |  |  |                 return real_entry_points.get(group, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         importlib_metadata = MagicMock() | 
					
						
							|  |  |  |         importlib_metadata.entry_points.return_value = FakeEntryPoints() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         orig_import = __import__ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def mock_import(name, *args, **kwargs): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             if name == "importlib.metadata": | 
					
						
							| 
									
										
										
										
											2024-06-14 17:27:22 -05:00
										 |  |  |                 raise ImportError | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             if name == "importlib_metadata": | 
					
						
							| 
									
										
										
										
											2024-06-14 17:27:22 -05:00
										 |  |  |                 return importlib_metadata | 
					
						
							|  |  |  |             return orig_import(name, *args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch("builtins.__import__", side_effect=mock_import): | 
					
						
							| 
									
										
										
										
											2024-06-14 17:27:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # load some entry points which should "always" be present, | 
					
						
							|  |  |  |             # even in a testing environment.  basic sanity check | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             result = mod.load_entry_points("console_scripts", ignore_errors=True) | 
					
						
							| 
									
										
										
										
											2024-06-14 17:27:22 -05:00
										 |  |  |             self.assertTrue(len(result) >= 1) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.assertIn("pytest", result) | 
					
						
							| 
									
										
										
										
											2023-11-19 14:22:25 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |     def test_error(self): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 23:32:11 -05:00
										 |  |  |         # skip if < 3.8 | 
					
						
							|  |  |  |         if sys.version_info.major == 3 and sys.version_info.minor < 8: | 
					
						
							|  |  |  |             pytest.skip("this requires python 3.8 for entry points via importlib") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         entry_point = MagicMock() | 
					
						
							| 
									
										
										
										
											2023-11-19 14:22:25 -06:00
										 |  |  |         entry_point.load.side_effect = NotImplementedError | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         entry_points = MagicMock() | 
					
						
							|  |  |  |         entry_points.select.return_value = [entry_point] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         importlib = MagicMock() | 
					
						
							|  |  |  |         importlib.metadata.entry_points.return_value = entry_points | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.dict("sys.modules", **{"importlib": importlib}): | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # empty set returned if errors suppressed | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             result = mod.load_entry_points("wuttatest.thingers", ignore_errors=True) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |             self.assertEqual(result, {}) | 
					
						
							|  |  |  |             importlib.metadata.entry_points.assert_called_once_with() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             entry_points.select.assert_called_once_with(group="wuttatest.thingers") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |             entry_point.load.assert_called_once_with() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # error is raised, if not suppressed | 
					
						
							|  |  |  |             importlib.metadata.entry_points.reset_mock() | 
					
						
							|  |  |  |             entry_points.select.reset_mock() | 
					
						
							|  |  |  |             entry_point.load.reset_mock() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.assertRaises( | 
					
						
							|  |  |  |                 NotImplementedError, mod.load_entry_points, "wuttatest.thingers" | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |             importlib.metadata.entry_points.assert_called_once_with() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             entry_points.select.assert_called_once_with(group="wuttatest.thingers") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |             entry_point.load.assert_called_once_with() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestLoadObject(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_missing_spec(self): | 
					
						
							| 
									
										
										
										
											2024-08-15 20:18:54 -05:00
										 |  |  |         self.assertRaises(ValueError, mod.load_object, None) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         result = mod.load_object("unittest:TestCase") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertIs(result, TestCase) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-11 12:55:55 -05:00
										 |  |  | class TestMakeUUID(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							| 
									
										
										
										
											2024-08-15 20:18:54 -05:00
										 |  |  |         uuid = mod.make_uuid() | 
					
						
							| 
									
										
										
										
											2024-07-11 12:55:55 -05:00
										 |  |  |         self.assertEqual(len(uuid), 32) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | class TestParseBool(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_null(self): | 
					
						
							| 
									
										
										
										
											2024-08-15 20:18:54 -05:00
										 |  |  |         self.assertIsNone(mod.parse_bool(None)) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_bool(self): | 
					
						
							| 
									
										
										
										
											2024-08-15 20:18:54 -05:00
										 |  |  |         self.assertTrue(mod.parse_bool(True)) | 
					
						
							|  |  |  |         self.assertFalse(mod.parse_bool(False)) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_string_true(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertTrue(mod.parse_bool("true")) | 
					
						
							|  |  |  |         self.assertTrue(mod.parse_bool("yes")) | 
					
						
							|  |  |  |         self.assertTrue(mod.parse_bool("y")) | 
					
						
							|  |  |  |         self.assertTrue(mod.parse_bool("on")) | 
					
						
							|  |  |  |         self.assertTrue(mod.parse_bool("1")) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_string_false(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertFalse(mod.parse_bool("false")) | 
					
						
							|  |  |  |         self.assertFalse(mod.parse_bool("no")) | 
					
						
							|  |  |  |         self.assertFalse(mod.parse_bool("n")) | 
					
						
							|  |  |  |         self.assertFalse(mod.parse_bool("off")) | 
					
						
							|  |  |  |         self.assertFalse(mod.parse_bool("0")) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         # nb. assume false for unrecognized input | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertFalse(mod.parse_bool("whatever-else")) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestParseList(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_null(self): | 
					
						
							| 
									
										
										
										
											2024-08-15 20:18:54 -05:00
										 |  |  |         value = mod.parse_list(None) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertIsInstance(value, list) | 
					
						
							|  |  |  |         self.assertEqual(len(value), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-19 20:36:51 -06:00
										 |  |  |     def test_list_instance(self): | 
					
						
							|  |  |  |         mylist = [] | 
					
						
							| 
									
										
										
										
											2024-08-15 20:18:54 -05:00
										 |  |  |         value = mod.parse_list(mylist) | 
					
						
							| 
									
										
										
										
											2023-11-19 20:36:51 -06:00
										 |  |  |         self.assertIs(value, mylist) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |     def test_single_value(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         value = mod.parse_list("foo") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertEqual(len(value), 1) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(value[0], "foo") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_single_value_padded_by_spaces(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         value = mod.parse_list("   foo   ") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertEqual(len(value), 1) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(value[0], "foo") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_slash_is_not_a_separator(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         value = mod.parse_list("/dev/null") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertEqual(len(value), 1) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(value[0], "/dev/null") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_multiple_values_separated_by_whitespace(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         value = mod.parse_list("foo bar baz") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertEqual(len(value), 3) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(value[0], "foo") | 
					
						
							|  |  |  |         self.assertEqual(value[1], "bar") | 
					
						
							|  |  |  |         self.assertEqual(value[2], "baz") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_multiple_values_separated_by_commas(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         value = mod.parse_list("foo,bar,baz") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertEqual(len(value), 3) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(value[0], "foo") | 
					
						
							|  |  |  |         self.assertEqual(value[1], "bar") | 
					
						
							|  |  |  |         self.assertEqual(value[2], "baz") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_multiple_values_separated_by_whitespace_and_commas(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         value = mod.parse_list("  foo,   bar   baz") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertEqual(len(value), 3) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(value[0], "foo") | 
					
						
							|  |  |  |         self.assertEqual(value[1], "bar") | 
					
						
							|  |  |  |         self.assertEqual(value[2], "baz") | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_multiple_values_separated_by_whitespace_and_commas_with_some_quoting(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         value = mod.parse_list( | 
					
						
							|  |  |  |             """
 | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         foo | 
					
						
							|  |  |  |         "C:\\some path\\with spaces\\and, a comma", | 
					
						
							|  |  |  |         baz | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertEqual(len(value), 3) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(value[0], "foo") | 
					
						
							|  |  |  |         self.assertEqual(value[1], "C:\\some path\\with spaces\\and, a comma") | 
					
						
							|  |  |  |         self.assertEqual(value[2], "baz") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_multiple_values_separated_by_whitespace_and_commas_with_single_quotes( | 
					
						
							|  |  |  |         self, | 
					
						
							|  |  |  |     ): | 
					
						
							|  |  |  |         value = mod.parse_list( | 
					
						
							|  |  |  |             """
 | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         foo | 
					
						
							|  |  |  |         'C:\\some path\\with spaces\\and, a comma', | 
					
						
							|  |  |  |         baz | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-10-28 17:48:37 -05:00
										 |  |  |         self.assertEqual(len(value), 3) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(value[0], "foo") | 
					
						
							|  |  |  |         self.assertEqual(value[1], "C:\\some path\\with spaces\\and, a comma") | 
					
						
							|  |  |  |         self.assertEqual(value[2], "baz") | 
					
						
							| 
									
										
										
										
											2024-08-04 14:23:02 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestMakeTitle(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         text = mod.make_title("foo_bar") | 
					
						
							| 
									
										
										
										
											2024-08-04 14:23:02 -05:00
										 |  |  |         self.assertEqual(text, "Foo Bar") | 
					
						
							| 
									
										
										
										
											2024-08-24 17:19:50 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-06 16:36:27 -06:00
										 |  |  | class TestMakeFullName(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         name = mod.make_full_name("Fred", "", "Flintstone", "") | 
					
						
							|  |  |  |         self.assertEqual(name, "Fred Flintstone") | 
					
						
							| 
									
										
										
										
											2025-01-06 16:36:27 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-24 17:19:50 -05:00
										 |  |  | class TestProgressLoop(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def act(obj, i): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # with progress | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         mod.progress_loop(act, [1, 2, 3], ProgressBase, message="whatever") | 
					
						
							| 
									
										
										
										
											2024-08-24 17:19:50 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # without progress | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         mod.progress_loop(act, [1, 2, 3], None, message="whatever") | 
					
						
							| 
									
										
										
										
											2024-08-26 10:12:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestResourcePath(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # package spec is resolved to path | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         path = mod.resource_path("wuttjamaican:util.py") | 
					
						
							|  |  |  |         self.assertTrue(path.endswith("wuttjamaican/util.py")) | 
					
						
							| 
									
										
										
										
											2024-08-26 10:12:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # absolute path returned as-is | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             mod.resource_path("/tmp/doesnotexist.txt"), "/tmp/doesnotexist.txt" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-26 10:12:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basic_pre_python_3_9(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # the goal here is to get coverage for code which would only | 
					
						
							|  |  |  |         # run on python 3.8 and older, but we only need that coverage | 
					
						
							|  |  |  |         # if we are currently testing python 3.9+ | 
					
						
							|  |  |  |         if sys.version_info.major == 3 and sys.version_info.minor < 9: | 
					
						
							|  |  |  |             pytest.skip("this test is not relevant before python 3.9") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         from importlib.resources import files, as_file | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         orig_import = __import__ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def mock_import(name, globals=None, locals=None, fromlist=(), level=0): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             if name == "importlib.resources": | 
					
						
							| 
									
										
										
										
											2024-08-26 10:12:52 -05:00
										 |  |  |                 raise ImportError | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             if name == "importlib_resources": | 
					
						
							| 
									
										
										
										
											2024-08-26 10:12:52 -05:00
										 |  |  |                 return MagicMock(files=files, as_file=as_file) | 
					
						
							|  |  |  |             return orig_import(name, globals, locals, fromlist, level) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch("builtins.__import__", side_effect=mock_import): | 
					
						
							| 
									
										
										
										
											2024-08-26 10:12:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # package spec is resolved to path | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             path = mod.resource_path("wuttjamaican:util.py") | 
					
						
							|  |  |  |             self.assertTrue(path.endswith("wuttjamaican/util.py")) | 
					
						
							| 
									
										
										
										
											2024-08-26 10:12:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # absolute path returned as-is | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.assertEqual( | 
					
						
							|  |  |  |                 mod.resource_path("/tmp/doesnotexist.txt"), "/tmp/doesnotexist.txt" | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-12-28 20:10:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestSimpleError(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_with_description(self): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             raise RuntimeError("just testin") | 
					
						
							|  |  |  |         except Exception as error: | 
					
						
							|  |  |  |             result = mod.simple_error(error) | 
					
						
							|  |  |  |         self.assertEqual(result, "RuntimeError: just testin") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_without_description(self): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             raise RuntimeError | 
					
						
							|  |  |  |         except Exception as error: | 
					
						
							|  |  |  |             result = mod.simple_error(error) | 
					
						
							|  |  |  |         self.assertEqual(result, "RuntimeError") |