|
1 |
| -import os |
2 |
| -import unittest |
3 |
| -from unittest.mock import patch, mock_open, call |
| 1 | +import unittest, json, os |
4 | 2 | from click.testing import CliRunner
|
5 | 3 | from replace_text.replace_text import replace_text
|
6 | 4 |
|
7 | 5 |
|
8 | 6 | class TestReplaceText(unittest.TestCase):
|
9 |
| - def assert_path_any_call(self, mock_obj, expected_path, mode, encoding): |
10 |
| - normalized_expected_path = os.path.normpath(expected_path) |
11 |
| - for mock_call in mock_obj.call_args_list: |
12 |
| - args, kwargs = mock_call |
13 |
| - if len(args) >= 1: |
14 |
| - normalized_actual_path = os.path.normpath(args[0]) |
15 |
| - if ( |
16 |
| - normalized_actual_path == normalized_expected_path |
17 |
| - and args[1] == mode |
18 |
| - and kwargs.get("encoding") == encoding |
19 |
| - ): |
20 |
| - return |
21 |
| - raise AssertionError( |
22 |
| - f"Expected call not found: open('{normalized_expected_path}', '{mode}', encoding='{encoding}')" |
23 |
| - ) |
| 7 | + def setUp(self): |
| 8 | + self.runner = CliRunner() |
| 9 | + self.test_folder = "test_folder" |
| 10 | + self.config_file = "config.json" |
| 11 | + |
| 12 | + # Create test folder and files |
| 13 | + os.makedirs(self.test_folder, exist_ok=True) |
| 14 | + with open(os.path.join(self.test_folder, "test1.txt"), "w") as f: |
| 15 | + f.write("Hello world") |
| 16 | + with open(os.path.join(self.test_folder, "test2.txt"), "w") as f: |
| 17 | + f.write("Python is awesome") |
24 | 18 |
|
25 |
| - @patch("builtins.open", new_callable=mock_open, read_data="key1 content key2") |
26 |
| - @patch("os.walk") |
27 |
| - @patch("json.load") |
28 |
| - def test_replace_text_keys_to_values_single_dict( |
29 |
| - self, mock_json_load, mock_os_walk, mock_file |
30 |
| - ): |
31 |
| - mock_json_load.return_value = { |
| 19 | + # Create config file |
| 20 | + config = { |
32 | 21 | "dictionaries": {
|
33 |
| - "example1": {"key1": "value1", "key2": "value2", "key3": "value3"} |
| 22 | + "test_dict": {"Hello": "Bonjour", "world": "monde", "Python": "Java"} |
34 | 23 | },
|
35 |
| - "ignore_extensions": [".png", ".jpg"], |
| 24 | + "ignore_extensions": [".ignore"], |
| 25 | + "ignore_directories": ["ignore_dir"], |
| 26 | + "ignore_file_prefixes": ["ignore_"], |
36 | 27 | }
|
37 |
| - mock_os_walk.return_value = [ |
38 |
| - ("/mocked/path", ("subdir",), ("file1.txt", "file2.jpg")) |
39 |
| - ] |
| 28 | + with open(self.config_file, "w") as f: |
| 29 | + json.dump(config, f) |
40 | 30 |
|
41 |
| - runner = CliRunner() |
42 |
| - result = runner.invoke( |
| 31 | + def tearDown(self): |
| 32 | + # Clean up test files and folders |
| 33 | + for root, dirs, files in os.walk(self.test_folder, topdown=False): |
| 34 | + for name in files: |
| 35 | + os.remove(os.path.join(root, name)) |
| 36 | + for name in dirs: |
| 37 | + os.rmdir(os.path.join(root, name)) |
| 38 | + os.rmdir(self.test_folder) |
| 39 | + os.remove(self.config_file) |
| 40 | + |
| 41 | + def test_replace_text_keys_to_values(self): |
| 42 | + result = self.runner.invoke( |
43 | 43 | replace_text,
|
44 |
| - ["--direction", "1", "--folder", "/mocked/path", "--dict-name", "example1"], |
| 44 | + [ |
| 45 | + "--direction", |
| 46 | + "1", |
| 47 | + "--folder", |
| 48 | + self.test_folder, |
| 49 | + "--dict-name", |
| 50 | + "test_dict", |
| 51 | + ], |
45 | 52 | )
|
46 |
| - |
47 |
| - self.assert_path_any_call(mock_file, "/mocked/path/file1.txt", "r", "utf-8") |
48 |
| - self.assert_path_any_call(mock_file, "/mocked/path/file1.txt", "w", "utf-8") |
49 |
| - mock_file().write.assert_called_with("value1 content value2") |
50 | 53 | self.assertEqual(result.exit_code, 0)
|
51 | 54 |
|
52 |
| - @patch("builtins.open", new_callable=mock_open, read_data="value1 content value2") |
53 |
| - @patch("os.walk") |
54 |
| - @patch("json.load") |
55 |
| - def test_replace_text_values_to_keys_multiple_dicts( |
56 |
| - self, mock_json_load, mock_os_walk, mock_file |
57 |
| - ): |
58 |
| - mock_json_load.return_value = { |
59 |
| - "dictionaries": { |
60 |
| - "example1": {"key1": "value1", "key2": "value2", "key3": "value3"}, |
61 |
| - "example2": {"hello": "world", "foo": "bar", "python": "rocks"}, |
62 |
| - }, |
63 |
| - "ignore_extensions": [".png", ".jpg"], |
64 |
| - } |
65 |
| - mock_os_walk.return_value = [ |
66 |
| - ("/mocked/path", ("subdir",), ("file1.txt", "file2.jpg")) |
67 |
| - ] |
| 55 | + with open(os.path.join(self.test_folder, "test1.txt"), "r") as f: |
| 56 | + content = f.read() |
| 57 | + self.assertEqual(content, "Bonjour monde") |
68 | 58 |
|
69 |
| - runner = CliRunner() |
70 |
| - result = runner.invoke( |
| 59 | + with open(os.path.join(self.test_folder, "test2.txt"), "r") as f: |
| 60 | + content = f.read() |
| 61 | + self.assertEqual(content, "Java is awesome") |
| 62 | + |
| 63 | + def test_replace_text_values_to_keys(self): |
| 64 | + # First, replace keys with values |
| 65 | + self.runner.invoke( |
71 | 66 | replace_text,
|
72 |
| - ["--direction", "2", "--folder", "/mocked/path", "--dict-name", "example1"], |
| 67 | + [ |
| 68 | + "--direction", |
| 69 | + "1", |
| 70 | + "--folder", |
| 71 | + self.test_folder, |
| 72 | + "--dict-name", |
| 73 | + "test_dict", |
| 74 | + ], |
73 | 75 | )
|
74 | 76 |
|
75 |
| - self.assert_path_any_call(mock_file, "/mocked/path/file1.txt", "r", "utf-8") |
76 |
| - self.assert_path_any_call(mock_file, "/mocked/path/file1.txt", "w", "utf-8") |
77 |
| - mock_file().write.assert_called_with("key1 content key2") |
| 77 | + # Then, test replacing values with keys |
| 78 | + result = self.runner.invoke( |
| 79 | + replace_text, |
| 80 | + [ |
| 81 | + "--direction", |
| 82 | + "2", |
| 83 | + "--folder", |
| 84 | + self.test_folder, |
| 85 | + "--dict-name", |
| 86 | + "test_dict", |
| 87 | + ], |
| 88 | + ) |
78 | 89 | self.assertEqual(result.exit_code, 0)
|
79 | 90 |
|
80 |
| - @patch("builtins.open", new_callable=mock_open, read_data="hello content foo") |
81 |
| - @patch("os.walk") |
82 |
| - @patch("json.load") |
83 |
| - def test_replace_text_with_dict_name_flag( |
84 |
| - self, mock_json_load, mock_os_walk, mock_file |
85 |
| - ): |
86 |
| - mock_json_load.return_value = { |
87 |
| - "dictionaries": { |
88 |
| - "example1": {"key1": "value1", "key2": "value2", "key3": "value3"}, |
89 |
| - "example2": {"hello": "world", "foo": "bar", "python": "rocks"}, |
90 |
| - }, |
91 |
| - "ignore_extensions": [".png", ".jpg"], |
92 |
| - } |
93 |
| - mock_os_walk.return_value = [ |
94 |
| - ("/mocked/path", ("subdir",), ("file1.txt", "file2.jpg")) |
95 |
| - ] |
| 91 | + with open(os.path.join(self.test_folder, "test1.txt"), "r") as f: |
| 92 | + content = f.read() |
| 93 | + self.assertEqual(content, "Hello world") |
| 94 | + |
| 95 | + with open(os.path.join(self.test_folder, "test2.txt"), "r") as f: |
| 96 | + content = f.read() |
| 97 | + self.assertEqual(content, "Python is awesome") |
96 | 98 |
|
97 |
| - runner = CliRunner() |
98 |
| - result = runner.invoke( |
| 99 | + def test_ignore_extensions(self): |
| 100 | + with open(os.path.join(self.test_folder, "test.ignore"), "w") as f: |
| 101 | + f.write("Hello world") |
| 102 | + |
| 103 | + result = self.runner.invoke( |
99 | 104 | replace_text,
|
100 |
| - ["--direction", "1", "--folder", "/mocked/path", "--dict-name", "example2"], |
| 105 | + [ |
| 106 | + "--direction", |
| 107 | + "1", |
| 108 | + "--folder", |
| 109 | + self.test_folder, |
| 110 | + "--dict-name", |
| 111 | + "test_dict", |
| 112 | + ], |
101 | 113 | )
|
| 114 | + self.assertEqual(result.exit_code, 0) |
| 115 | + |
| 116 | + with open(os.path.join(self.test_folder, "test.ignore"), "r") as f: |
| 117 | + content = f.read() |
| 118 | + self.assertEqual(content, "Hello world") # Content should remain unchanged |
| 119 | + |
| 120 | + def test_ignore_directories(self): |
| 121 | + os.makedirs(os.path.join(self.test_folder, "ignore_dir"), exist_ok=True) |
| 122 | + with open(os.path.join(self.test_folder, "ignore_dir", "test.txt"), "w") as f: |
| 123 | + f.write("Hello world") |
102 | 124 |
|
103 |
| - self.assert_path_any_call(mock_file, "/mocked/path/file1.txt", "r", "utf-8") |
104 |
| - self.assert_path_any_call(mock_file, "/mocked/path/file1.txt", "w", "utf-8") |
105 |
| - mock_file().write.assert_called_with("world content bar") |
| 125 | + result = self.runner.invoke( |
| 126 | + replace_text, |
| 127 | + [ |
| 128 | + "--direction", |
| 129 | + "1", |
| 130 | + "--folder", |
| 131 | + self.test_folder, |
| 132 | + "--dict-name", |
| 133 | + "test_dict", |
| 134 | + ], |
| 135 | + ) |
106 | 136 | self.assertEqual(result.exit_code, 0)
|
107 | 137 |
|
| 138 | + with open(os.path.join(self.test_folder, "ignore_dir", "test.txt"), "r") as f: |
| 139 | + content = f.read() |
| 140 | + self.assertEqual(content, "Hello world") # Content should remain unchanged |
| 141 | + |
| 142 | + def test_ignore_file_prefixes(self): |
| 143 | + with open(os.path.join(self.test_folder, "ignore_test.txt"), "w") as f: |
| 144 | + f.write("Hello world") |
| 145 | + |
| 146 | + result = self.runner.invoke( |
| 147 | + replace_text, |
| 148 | + [ |
| 149 | + "--direction", |
| 150 | + "1", |
| 151 | + "--folder", |
| 152 | + self.test_folder, |
| 153 | + "--dict-name", |
| 154 | + "test_dict", |
| 155 | + ], |
| 156 | + ) |
| 157 | + self.assertEqual(result.exit_code, 0) |
| 158 | + |
| 159 | + with open(os.path.join(self.test_folder, "ignore_test.txt"), "r") as f: |
| 160 | + content = f.read() |
| 161 | + self.assertEqual(content, "Hello world") # Content should remain unchanged |
| 162 | + |
108 | 163 |
|
109 | 164 | if __name__ == "__main__":
|
110 | 165 | unittest.main()
|
0 commit comments