| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  | "Test squeezer, coverage 95%" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-24 14:05:51 +02:00
										 |  |  | from textwrap import dedent | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  | from tkinter import Text, Tk | 
					
						
							|  |  |  | import unittest | 
					
						
							|  |  |  | from unittest.mock import Mock, NonCallableMagicMock, patch, sentinel, ANY | 
					
						
							|  |  |  | from test.support import requires | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from idlelib.config import idleConf | 
					
						
							| 
									
										
										
										
											2021-04-29 01:27:55 +03:00
										 |  |  | from idlelib.percolator import Percolator | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  | from idlelib.squeezer import count_lines_with_wrapping, ExpandingButton, \ | 
					
						
							|  |  |  |     Squeezer | 
					
						
							|  |  |  | from idlelib import macosx | 
					
						
							|  |  |  | from idlelib.textview import view_text | 
					
						
							|  |  |  | from idlelib.tooltip import Hovertip | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SENTINEL_VALUE = sentinel.SENTINEL_VALUE | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_test_tk_root(test_instance): | 
					
						
							|  |  |  |     """Helper for tests: Create a root Tk object.""" | 
					
						
							|  |  |  |     requires('gui') | 
					
						
							|  |  |  |     root = Tk() | 
					
						
							|  |  |  |     root.withdraw() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def cleanup_root(): | 
					
						
							|  |  |  |         root.update_idletasks() | 
					
						
							|  |  |  |         root.destroy() | 
					
						
							|  |  |  |     test_instance.addCleanup(cleanup_root) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return root | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CountLinesTest(unittest.TestCase): | 
					
						
							|  |  |  |     """Tests for the count_lines_with_wrapping function.""" | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |     def check(self, expected, text, linewidth): | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         return self.assertEqual( | 
					
						
							|  |  |  |             expected, | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |             count_lines_with_wrapping(text, linewidth), | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_count_empty(self): | 
					
						
							|  |  |  |         """Test with an empty string.""" | 
					
						
							|  |  |  |         self.assertEqual(count_lines_with_wrapping(""), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_count_begins_with_empty_line(self): | 
					
						
							|  |  |  |         """Test with a string which begins with a newline.""" | 
					
						
							|  |  |  |         self.assertEqual(count_lines_with_wrapping("\ntext"), 2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_count_ends_with_empty_line(self): | 
					
						
							|  |  |  |         """Test with a string which ends with a newline.""" | 
					
						
							|  |  |  |         self.assertEqual(count_lines_with_wrapping("text\n"), 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_count_several_lines(self): | 
					
						
							|  |  |  |         """Test with several lines of text.""" | 
					
						
							|  |  |  |         self.assertEqual(count_lines_with_wrapping("1\n2\n3\n"), 3) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-24 14:05:51 +02:00
										 |  |  |     def test_empty_lines(self): | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         self.check(expected=1, text='\n', linewidth=80) | 
					
						
							|  |  |  |         self.check(expected=2, text='\n\n', linewidth=80) | 
					
						
							|  |  |  |         self.check(expected=10, text='\n' * 10, linewidth=80) | 
					
						
							| 
									
										
										
										
											2018-12-24 14:05:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_long_line(self): | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         self.check(expected=3, text='a' * 200, linewidth=80) | 
					
						
							|  |  |  |         self.check(expected=3, text='a' * 200 + '\n', linewidth=80) | 
					
						
							| 
									
										
										
										
											2018-12-24 14:05:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_several_lines_different_lengths(self): | 
					
						
							|  |  |  |         text = dedent("""\
 | 
					
						
							|  |  |  |             13 characters | 
					
						
							|  |  |  |             43 is the number of characters on this line | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             7 chars | 
					
						
							|  |  |  |             13 characters""")
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         self.check(expected=5, text=text, linewidth=80) | 
					
						
							|  |  |  |         self.check(expected=5, text=text + '\n', linewidth=80) | 
					
						
							|  |  |  |         self.check(expected=6, text=text, linewidth=40) | 
					
						
							|  |  |  |         self.check(expected=7, text=text, linewidth=20) | 
					
						
							|  |  |  |         self.check(expected=11, text=text, linewidth=10) | 
					
						
							| 
									
										
										
										
											2018-12-24 14:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | class SqueezerTest(unittest.TestCase): | 
					
						
							|  |  |  |     """Tests for the Squeezer class.""" | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |     def make_mock_editor_window(self, with_text_widget=False): | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         """Create a mock EditorWindow instance.""" | 
					
						
							|  |  |  |         editwin = NonCallableMagicMock() | 
					
						
							| 
									
										
										
										
											2019-08-25 08:52:58 +03:00
										 |  |  |         editwin.width = 80 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if with_text_widget: | 
					
						
							|  |  |  |             editwin.root = get_test_tk_root(self) | 
					
						
							|  |  |  |             text_widget = self.make_text_widget(root=editwin.root) | 
					
						
							|  |  |  |             editwin.text = editwin.per.bottom = text_widget | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         return editwin | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def make_squeezer_instance(self, editor_window=None): | 
					
						
							|  |  |  |         """Create an actual Squeezer instance with a mock EditorWindow.""" | 
					
						
							|  |  |  |         if editor_window is None: | 
					
						
							|  |  |  |             editor_window = self.make_mock_editor_window() | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         squeezer = Squeezer(editor_window) | 
					
						
							|  |  |  |         return squeezer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def make_text_widget(self, root=None): | 
					
						
							|  |  |  |         if root is None: | 
					
						
							|  |  |  |             root = get_test_tk_root(self) | 
					
						
							|  |  |  |         text_widget = Text(root) | 
					
						
							|  |  |  |         text_widget["font"] = ('Courier', 10) | 
					
						
							|  |  |  |         text_widget.mark_set("iomark", "1.0") | 
					
						
							|  |  |  |         return text_widget | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_idleconf_option_with_cleanup(self, configType, section, option, value): | 
					
						
							|  |  |  |         prev_val = idleConf.GetOption(configType, section, option) | 
					
						
							|  |  |  |         idleConf.SetOption(configType, section, option, value) | 
					
						
							|  |  |  |         self.addCleanup(idleConf.SetOption, | 
					
						
							|  |  |  |                         configType, section, option, prev_val) | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_count_lines(self): | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         """Test Squeezer.count_lines() with various inputs.""" | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         editwin = self.make_mock_editor_window() | 
					
						
							|  |  |  |         squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         for text_code, line_width, expected in [ | 
					
						
							|  |  |  |             (r"'\n'", 80, 1), | 
					
						
							|  |  |  |             (r"'\n' * 3", 80, 3), | 
					
						
							|  |  |  |             (r"'a' * 40 + '\n'", 80, 1), | 
					
						
							|  |  |  |             (r"'a' * 80 + '\n'", 80, 1), | 
					
						
							|  |  |  |             (r"'a' * 200 + '\n'", 80, 3), | 
					
						
							|  |  |  |             (r"'aa\t' * 20", 80, 2), | 
					
						
							|  |  |  |             (r"'aa\t' * 21", 80, 3), | 
					
						
							|  |  |  |             (r"'aa\t' * 20", 40, 4), | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             with self.subTest(text_code=text_code, | 
					
						
							|  |  |  |                               line_width=line_width, | 
					
						
							|  |  |  |                               expected=expected): | 
					
						
							|  |  |  |                 text = eval(text_code) | 
					
						
							| 
									
										
										
										
											2019-08-25 08:52:58 +03:00
										 |  |  |                 with patch.object(editwin, 'width', line_width): | 
					
						
							|  |  |  |                     self.assertEqual(squeezer.count_lines(text), expected) | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_init(self): | 
					
						
							|  |  |  |         """Test the creation of Squeezer instances.""" | 
					
						
							|  |  |  |         editwin = self.make_mock_editor_window() | 
					
						
							|  |  |  |         squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  |         self.assertIs(squeezer.editwin, editwin) | 
					
						
							|  |  |  |         self.assertEqual(squeezer.expandingbuttons, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_write_no_tags(self): | 
					
						
							|  |  |  |         """Test Squeezer's overriding of the EditorWindow's write() method.""" | 
					
						
							|  |  |  |         editwin = self.make_mock_editor_window() | 
					
						
							|  |  |  |         for text in ['', 'TEXT', 'LONG TEXT' * 1000, 'MANY_LINES\n' * 100]: | 
					
						
							|  |  |  |             editwin.write = orig_write = Mock(return_value=SENTINEL_VALUE) | 
					
						
							|  |  |  |             squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.assertEqual(squeezer.editwin.write(text, ()), SENTINEL_VALUE) | 
					
						
							|  |  |  |             self.assertEqual(orig_write.call_count, 1) | 
					
						
							|  |  |  |             orig_write.assert_called_with(text, ()) | 
					
						
							|  |  |  |             self.assertEqual(len(squeezer.expandingbuttons), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_write_not_stdout(self): | 
					
						
							|  |  |  |         """Test Squeezer's overriding of the EditorWindow's write() method.""" | 
					
						
							|  |  |  |         for text in ['', 'TEXT', 'LONG TEXT' * 1000, 'MANY_LINES\n' * 100]: | 
					
						
							|  |  |  |             editwin = self.make_mock_editor_window() | 
					
						
							|  |  |  |             editwin.write.return_value = SENTINEL_VALUE | 
					
						
							|  |  |  |             orig_write = editwin.write | 
					
						
							|  |  |  |             squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.assertEqual(squeezer.editwin.write(text, "stderr"), | 
					
						
							|  |  |  |                               SENTINEL_VALUE) | 
					
						
							|  |  |  |             self.assertEqual(orig_write.call_count, 1) | 
					
						
							|  |  |  |             orig_write.assert_called_with(text, "stderr") | 
					
						
							|  |  |  |             self.assertEqual(len(squeezer.expandingbuttons), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_write_stdout(self): | 
					
						
							|  |  |  |         """Test Squeezer's overriding of the EditorWindow's write() method.""" | 
					
						
							|  |  |  |         editwin = self.make_mock_editor_window() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for text in ['', 'TEXT']: | 
					
						
							|  |  |  |             editwin.write = orig_write = Mock(return_value=SENTINEL_VALUE) | 
					
						
							|  |  |  |             squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  |             squeezer.auto_squeeze_min_lines = 50 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.assertEqual(squeezer.editwin.write(text, "stdout"), | 
					
						
							|  |  |  |                              SENTINEL_VALUE) | 
					
						
							|  |  |  |             self.assertEqual(orig_write.call_count, 1) | 
					
						
							|  |  |  |             orig_write.assert_called_with(text, "stdout") | 
					
						
							|  |  |  |             self.assertEqual(len(squeezer.expandingbuttons), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for text in ['LONG TEXT' * 1000, 'MANY_LINES\n' * 100]: | 
					
						
							|  |  |  |             editwin.write = orig_write = Mock(return_value=SENTINEL_VALUE) | 
					
						
							|  |  |  |             squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  |             squeezer.auto_squeeze_min_lines = 50 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.assertEqual(squeezer.editwin.write(text, "stdout"), None) | 
					
						
							|  |  |  |             self.assertEqual(orig_write.call_count, 0) | 
					
						
							|  |  |  |             self.assertEqual(len(squeezer.expandingbuttons), 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_auto_squeeze(self): | 
					
						
							|  |  |  |         """Test that the auto-squeezing creates an ExpandingButton properly.""" | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         editwin = self.make_mock_editor_window(with_text_widget=True) | 
					
						
							|  |  |  |         text_widget = editwin.text | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  |         squeezer.auto_squeeze_min_lines = 5 | 
					
						
							|  |  |  |         squeezer.count_lines = Mock(return_value=6) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         editwin.write('TEXT\n'*6, "stdout") | 
					
						
							|  |  |  |         self.assertEqual(text_widget.get('1.0', 'end'), '\n') | 
					
						
							|  |  |  |         self.assertEqual(len(squeezer.expandingbuttons), 1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-29 01:27:55 +03:00
										 |  |  |     def test_squeeze_current_text(self): | 
					
						
							|  |  |  |         """Test the squeeze_current_text method.""" | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Squeezing text should work for both stdout and stderr. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         for tag_name in ["stdout", "stderr"]: | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |             editwin = self.make_mock_editor_window(with_text_widget=True) | 
					
						
							|  |  |  |             text_widget = editwin.text | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  |             squeezer.count_lines = Mock(return_value=6) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |             # Prepare some text in the Text widget. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             text_widget.insert("1.0", "SOME\nTEXT\n", tag_name) | 
					
						
							|  |  |  |             text_widget.mark_set("insert", "1.0") | 
					
						
							|  |  |  |             self.assertEqual(text_widget.get('1.0', 'end'), 'SOME\nTEXT\n\n') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.assertEqual(len(squeezer.expandingbuttons), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |             # Test squeezing the current text. | 
					
						
							| 
									
										
										
										
											2021-04-29 01:27:55 +03:00
										 |  |  |             retval = squeezer.squeeze_current_text() | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             self.assertEqual(retval, "break") | 
					
						
							|  |  |  |             self.assertEqual(text_widget.get('1.0', 'end'), '\n\n') | 
					
						
							|  |  |  |             self.assertEqual(len(squeezer.expandingbuttons), 1) | 
					
						
							|  |  |  |             self.assertEqual(squeezer.expandingbuttons[0].s, 'SOME\nTEXT') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |             # Test that expanding the squeezed text works and afterwards | 
					
						
							|  |  |  |             # the Text widget contains the original text. | 
					
						
							| 
									
										
										
										
											2021-04-29 01:27:55 +03:00
										 |  |  |             squeezer.expandingbuttons[0].expand() | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             self.assertEqual(text_widget.get('1.0', 'end'), 'SOME\nTEXT\n\n') | 
					
						
							|  |  |  |             self.assertEqual(len(squeezer.expandingbuttons), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-29 01:27:55 +03:00
										 |  |  |     def test_squeeze_current_text_no_allowed_tags(self): | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         """Test that the event doesn't squeeze text without a relevant tag.""" | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         editwin = self.make_mock_editor_window(with_text_widget=True) | 
					
						
							|  |  |  |         text_widget = editwin.text | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  |         squeezer.count_lines = Mock(return_value=6) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Prepare some text in the Text widget. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         text_widget.insert("1.0", "SOME\nTEXT\n", "TAG") | 
					
						
							|  |  |  |         text_widget.mark_set("insert", "1.0") | 
					
						
							|  |  |  |         self.assertEqual(text_widget.get('1.0', 'end'), 'SOME\nTEXT\n\n') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(len(squeezer.expandingbuttons), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Test squeezing the current text. | 
					
						
							| 
									
										
										
										
											2021-04-29 01:27:55 +03:00
										 |  |  |         retval = squeezer.squeeze_current_text() | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(retval, "break") | 
					
						
							|  |  |  |         self.assertEqual(text_widget.get('1.0', 'end'), 'SOME\nTEXT\n\n') | 
					
						
							|  |  |  |         self.assertEqual(len(squeezer.expandingbuttons), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_squeeze_text_before_existing_squeezed_text(self): | 
					
						
							|  |  |  |         """Test squeezing text before existing squeezed text.""" | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         editwin = self.make_mock_editor_window(with_text_widget=True) | 
					
						
							|  |  |  |         text_widget = editwin.text | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  |         squeezer.count_lines = Mock(return_value=6) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Prepare some text in the Text widget and squeeze it. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         text_widget.insert("1.0", "SOME\nTEXT\n", "stdout") | 
					
						
							|  |  |  |         text_widget.mark_set("insert", "1.0") | 
					
						
							| 
									
										
										
										
											2021-04-29 01:27:55 +03:00
										 |  |  |         squeezer.squeeze_current_text() | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(len(squeezer.expandingbuttons), 1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Test squeezing the current text. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         text_widget.insert("1.0", "MORE\nSTUFF\n", "stdout") | 
					
						
							|  |  |  |         text_widget.mark_set("insert", "1.0") | 
					
						
							| 
									
										
										
										
											2021-04-29 01:27:55 +03:00
										 |  |  |         retval = squeezer.squeeze_current_text() | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(retval, "break") | 
					
						
							|  |  |  |         self.assertEqual(text_widget.get('1.0', 'end'), '\n\n\n') | 
					
						
							|  |  |  |         self.assertEqual(len(squeezer.expandingbuttons), 2) | 
					
						
							|  |  |  |         self.assertTrue(text_widget.compare( | 
					
						
							|  |  |  |             squeezer.expandingbuttons[0], | 
					
						
							|  |  |  |             '<', | 
					
						
							|  |  |  |             squeezer.expandingbuttons[1], | 
					
						
							|  |  |  |         )) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_reload(self): | 
					
						
							|  |  |  |         """Test the reload() class-method.""" | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         editwin = self.make_mock_editor_window(with_text_widget=True) | 
					
						
							|  |  |  |         squeezer = self.make_squeezer_instance(editwin) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         orig_auto_squeeze_min_lines = squeezer.auto_squeeze_min_lines | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-18 04:26:06 +02:00
										 |  |  |         # Increase auto-squeeze-min-lines. | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         new_auto_squeeze_min_lines = orig_auto_squeeze_min_lines + 10 | 
					
						
							|  |  |  |         self.set_idleconf_option_with_cleanup( | 
					
						
							|  |  |  |             'main', 'PyShell', 'auto-squeeze-min-lines', | 
					
						
							|  |  |  |             str(new_auto_squeeze_min_lines)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Squeezer.reload() | 
					
						
							|  |  |  |         self.assertEqual(squeezer.auto_squeeze_min_lines, | 
					
						
							|  |  |  |                          new_auto_squeeze_min_lines) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_reload_no_squeezer_instances(self): | 
					
						
							|  |  |  |         """Test that Squeezer.reload() runs without any instances existing.""" | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         Squeezer.reload() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ExpandingButtonTest(unittest.TestCase): | 
					
						
							|  |  |  |     """Tests for the ExpandingButton class.""" | 
					
						
							|  |  |  |     # In these tests the squeezer instance is a mock, but actual tkinter | 
					
						
							|  |  |  |     # Text and Button instances are created. | 
					
						
							|  |  |  |     def make_mock_squeezer(self): | 
					
						
							|  |  |  |         """Helper for tests: Create a mock Squeezer object.""" | 
					
						
							|  |  |  |         root = get_test_tk_root(self) | 
					
						
							|  |  |  |         squeezer = Mock() | 
					
						
							|  |  |  |         squeezer.editwin.text = Text(root) | 
					
						
							| 
									
										
										
										
											2021-04-29 01:27:55 +03:00
										 |  |  |         squeezer.editwin.per = Percolator(squeezer.editwin.text) | 
					
						
							| 
									
										
										
										
											2021-04-30 19:34:29 +01:00
										 |  |  |         self.addCleanup(squeezer.editwin.per.close) | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Set default values for the configuration settings. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         squeezer.auto_squeeze_min_lines = 50 | 
					
						
							|  |  |  |         return squeezer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @patch('idlelib.squeezer.Hovertip', autospec=Hovertip) | 
					
						
							|  |  |  |     def test_init(self, MockHovertip): | 
					
						
							|  |  |  |         """Test the simplest creation of an ExpandingButton.""" | 
					
						
							|  |  |  |         squeezer = self.make_mock_squeezer() | 
					
						
							|  |  |  |         text_widget = squeezer.editwin.text | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expandingbutton = ExpandingButton('TEXT', 'TAGS', 50, squeezer) | 
					
						
							|  |  |  |         self.assertEqual(expandingbutton.s, 'TEXT') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Check that the underlying tkinter.Button is properly configured. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(expandingbutton.master, text_widget) | 
					
						
							|  |  |  |         self.assertTrue('50 lines' in expandingbutton.cget('text')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Check that the text widget still contains no text. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(text_widget.get('1.0', 'end'), '\n') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Check that the mouse events are bound. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertIn('<Double-Button-1>', expandingbutton.bind()) | 
					
						
							|  |  |  |         right_button_code = '<Button-%s>' % ('2' if macosx.isAquaTk() else '3') | 
					
						
							|  |  |  |         self.assertIn(right_button_code, expandingbutton.bind()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Check that ToolTip was called once, with appropriate values. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(MockHovertip.call_count, 1) | 
					
						
							|  |  |  |         MockHovertip.assert_called_with(expandingbutton, ANY, hover_delay=ANY) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Check that 'right-click' appears in the tooltip text. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         tooltip_text = MockHovertip.call_args[0][1] | 
					
						
							|  |  |  |         self.assertIn('right-click', tooltip_text.lower()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_expand(self): | 
					
						
							|  |  |  |         """Test the expand event.""" | 
					
						
							|  |  |  |         squeezer = self.make_mock_squeezer() | 
					
						
							|  |  |  |         expandingbutton = ExpandingButton('TEXT', 'TAGS', 50, squeezer) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Insert the button into the text widget | 
					
						
							|  |  |  |         # (this is normally done by the Squeezer class). | 
					
						
							| 
									
										
										
										
											2021-04-29 01:27:55 +03:00
										 |  |  |         text_widget = squeezer.editwin.text | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         text_widget.window_create("1.0", window=expandingbutton) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # trigger the expand event | 
					
						
							|  |  |  |         retval = expandingbutton.expand(event=Mock()) | 
					
						
							|  |  |  |         self.assertEqual(retval, None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Check that the text was inserted into the text widget. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(text_widget.get('1.0', 'end'), 'TEXT\n') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Check that the 'TAGS' tag was set on the inserted text. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         text_end_index = text_widget.index('end-1c') | 
					
						
							|  |  |  |         self.assertEqual(text_widget.get('1.0', text_end_index), 'TEXT') | 
					
						
							|  |  |  |         self.assertEqual(text_widget.tag_nextrange('TAGS', '1.0'), | 
					
						
							|  |  |  |                           ('1.0', text_end_index)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Check that the button removed itself from squeezer.expandingbuttons. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(squeezer.expandingbuttons.remove.call_count, 1) | 
					
						
							|  |  |  |         squeezer.expandingbuttons.remove.assert_called_with(expandingbutton) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_expand_dangerous_oupput(self): | 
					
						
							|  |  |  |         """Test that expanding very long output asks user for confirmation.""" | 
					
						
							|  |  |  |         squeezer = self.make_mock_squeezer() | 
					
						
							|  |  |  |         text = 'a' * 10**5 | 
					
						
							|  |  |  |         expandingbutton = ExpandingButton(text, 'TAGS', 50, squeezer) | 
					
						
							|  |  |  |         expandingbutton.set_is_dangerous() | 
					
						
							|  |  |  |         self.assertTrue(expandingbutton.is_dangerous) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Insert the button into the text widget | 
					
						
							|  |  |  |         # (this is normally done by the Squeezer class). | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         text_widget = expandingbutton.text | 
					
						
							|  |  |  |         text_widget.window_create("1.0", window=expandingbutton) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Patch the message box module to always return False. | 
					
						
							| 
									
										
										
										
											2021-01-25 06:33:18 -05:00
										 |  |  |         with patch('idlelib.squeezer.messagebox') as mock_msgbox: | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             mock_msgbox.askokcancel.return_value = False | 
					
						
							|  |  |  |             mock_msgbox.askyesno.return_value = False | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |             # Trigger the expand event. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             retval = expandingbutton.expand(event=Mock()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Check that the event chain was broken and no text was inserted. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(retval, 'break') | 
					
						
							|  |  |  |         self.assertEqual(expandingbutton.text.get('1.0', 'end-1c'), '') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Patch the message box module to always return True. | 
					
						
							| 
									
										
										
										
											2021-01-25 06:33:18 -05:00
										 |  |  |         with patch('idlelib.squeezer.messagebox') as mock_msgbox: | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             mock_msgbox.askokcancel.return_value = True | 
					
						
							|  |  |  |             mock_msgbox.askyesno.return_value = True | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |             # Trigger the expand event. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             retval = expandingbutton.expand(event=Mock()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Check that the event chain wasn't broken and the text was inserted. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(retval, None) | 
					
						
							|  |  |  |         self.assertEqual(expandingbutton.text.get('1.0', 'end-1c'), text) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_copy(self): | 
					
						
							|  |  |  |         """Test the copy event.""" | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Testing with the actual clipboard proved problematic, so this | 
					
						
							|  |  |  |         # test replaces the clipboard manipulation functions with mocks | 
					
						
							|  |  |  |         # and checks that they are called appropriately. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         squeezer = self.make_mock_squeezer() | 
					
						
							|  |  |  |         expandingbutton = ExpandingButton('TEXT', 'TAGS', 50, squeezer) | 
					
						
							|  |  |  |         expandingbutton.clipboard_clear = Mock() | 
					
						
							|  |  |  |         expandingbutton.clipboard_append = Mock() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Trigger the copy event. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         retval = expandingbutton.copy(event=Mock()) | 
					
						
							|  |  |  |         self.assertEqual(retval, None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |         # Vheck that the expanding button called clipboard_clear() and | 
					
						
							|  |  |  |         # clipboard_append('TEXT') once each. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |         self.assertEqual(expandingbutton.clipboard_clear.call_count, 1) | 
					
						
							|  |  |  |         self.assertEqual(expandingbutton.clipboard_append.call_count, 1) | 
					
						
							|  |  |  |         expandingbutton.clipboard_append.assert_called_with('TEXT') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_view(self): | 
					
						
							|  |  |  |         """Test the view event.""" | 
					
						
							|  |  |  |         squeezer = self.make_mock_squeezer() | 
					
						
							|  |  |  |         expandingbutton = ExpandingButton('TEXT', 'TAGS', 50, squeezer) | 
					
						
							|  |  |  |         expandingbutton.selection_own = Mock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with patch('idlelib.squeezer.view_text', autospec=view_text)\ | 
					
						
							|  |  |  |                 as mock_view_text: | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |             # Trigger the view event. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             expandingbutton.view(event=Mock()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |             # Check that the expanding button called view_text. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             self.assertEqual(mock_view_text.call_count, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-13 17:01:50 +02:00
										 |  |  |             # Check that the proper text was passed. | 
					
						
							| 
									
										
										
										
											2018-09-25 15:10:14 +03:00
										 |  |  |             self.assertEqual(mock_view_text.call_args[0][2], 'TEXT') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_rmenu(self): | 
					
						
							|  |  |  |         """Test the context menu.""" | 
					
						
							|  |  |  |         squeezer = self.make_mock_squeezer() | 
					
						
							|  |  |  |         expandingbutton = ExpandingButton('TEXT', 'TAGS', 50, squeezer) | 
					
						
							|  |  |  |         with patch('tkinter.Menu') as mock_Menu: | 
					
						
							|  |  |  |             mock_menu = Mock() | 
					
						
							|  |  |  |             mock_Menu.return_value = mock_menu | 
					
						
							|  |  |  |             mock_event = Mock() | 
					
						
							|  |  |  |             mock_event.x = 10 | 
					
						
							|  |  |  |             mock_event.y = 10 | 
					
						
							|  |  |  |             expandingbutton.context_menu_event(event=mock_event) | 
					
						
							|  |  |  |             self.assertEqual(mock_menu.add_command.call_count, | 
					
						
							|  |  |  |                              len(expandingbutton.rmenu_specs)) | 
					
						
							|  |  |  |             for label, *data in expandingbutton.rmenu_specs: | 
					
						
							|  |  |  |                 mock_menu.add_command.assert_any_call(label=label, command=ANY) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     unittest.main(verbosity=2) |