cpython/Lib/idlelib/idle_test/test_iomenu.py

190 lines
5.9 KiB
Python

"Test , coverage 17%."
from idlelib import iomenu
import builtins
import os
import tempfile
import unittest
from unittest.mock import patch
from test.support import requires
from tkinter import Tk
from idlelib.editor import EditorWindow
from idlelib import util
from idlelib.idle_test.mock_idle import Func
# Fail if either tokenize.open and t.detect_encoding does not exist.
# These are used in loadfile and encode.
# Also used in pyshell.MI.execfile and runscript.tabnanny.
from tokenize import open, detect_encoding
# Remove when we have proper tests that use both.
class IOBindingTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
cls.editwin = EditorWindow(root=cls.root)
cls.io = iomenu.IOBinding(cls.editwin)
@classmethod
def tearDownClass(cls):
cls.io.close()
cls.editwin._close()
del cls.editwin
cls.root.update_idletasks()
for id in cls.root.tk.call('after', 'info'):
cls.root.after_cancel(id) # Need for EditorWindow.
cls.root.destroy()
del cls.root
def test_init(self):
self.assertIs(self.io.editwin, self.editwin)
def test_fixnewlines_end(self):
eq = self.assertEqual
io = self.io
fix = io.fixnewlines
text = io.editwin.text
# Make the editor temporarily look like Shell.
self.editwin.interp = None
shelltext = '>>> if 1'
self.editwin.get_prompt_text = Func(result=shelltext)
eq(fix(), shelltext) # Get... call and '\n' not added.
del self.editwin.interp, self.editwin.get_prompt_text
text.insert(1.0, 'a')
eq(fix(), 'a'+io.eol_convention)
eq(text.get('1.0', 'end-1c'), 'a\n')
eq(fix(), 'a'+io.eol_convention)
def test_reload_no_file(self):
# Test reload when no file is associated
io = self.io
# Ensure no filename is set
io.filename = None
# Mock the messagebox.showinfo using unittest.mock
with patch.object(iomenu.messagebox, 'showinfo') as mock_showinfo:
result = io.reload(None)
self.assertEqual(result, "break")
mock_showinfo.assert_called_once()
args, kwargs = mock_showinfo.call_args
self.assertIn("File Not Found", args[0])
def test_reload_with_file(self):
# Test reload with an actual file
io = self.io
text = io.editwin.text
# Create a temporary file
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.py') as f:
f.write("# Original content\n")
temp_filename = f.name
self.addCleanup(os.unlink, temp_filename)
# Load the file
io.loadfile(temp_filename)
self.assertEqual(text.get('1.0', 'end-1c'), "# Original content\n")
# Modify the file content externally
with builtins.open(temp_filename, 'w') as f:
f.write("# Modified content\n")
# Reload should update the content
result = io.reload(None)
self.assertEqual(result, "break")
self.assertEqual(text.get('1.0', 'end-1c'), "# Modified content\n")
def test_reload_with_unsaved_changes_cancel(self):
# Test reload with unsaved changes and user cancels
io = self.io
text = io.editwin.text
# Create a temporary file
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.py') as f:
f.write("# Original content\n")
temp_filename = f.name
self.addCleanup(os.unlink, temp_filename)
# Load the file
io.loadfile(temp_filename)
# Make unsaved changes
text.insert('end-1c', "\n# Unsaved change")
io.set_saved(False)
# Mock askokcancel to return False (cancel)
orig_askokcancel = iomenu.messagebox.askokcancel
iomenu.messagebox.askokcancel = lambda *args, **kwargs: False
try:
result = io.reload(None)
self.assertEqual(result, "break")
# Content should not change
self.assertIn("# Unsaved change", text.get('1.0', 'end-1c'))
finally:
iomenu.messagebox.askokcancel = orig_askokcancel
def test_reload_with_unsaved_changes_confirm(self):
# Test reload with unsaved changes and user confirms
io = self.io
text = io.editwin.text
# Create a temporary file
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.py') as f:
f.write("# Original content\n")
temp_filename = f.name
self.addCleanup(os.unlink, temp_filename)
# Load the file
io.loadfile(temp_filename)
# Make unsaved changes
text.insert('end-1c', "\n# Unsaved change")
io.set_saved(False)
# Mock askokcancel to return True (confirm)
orig_askokcancel = iomenu.messagebox.askokcancel
iomenu.messagebox.askokcancel = lambda *args, **kwargs: True
try:
result = io.reload(None)
self.assertEqual(result, "break")
# Content should be reverted to original
self.assertEqual(text.get('1.0', 'end-1c'), "# Original content\n")
finally:
iomenu.messagebox.askokcancel = orig_askokcancel
def _extension_in_filetypes(extension):
return any(
f'*{extension}' in filetype_tuple[1]
for filetype_tuple in iomenu.IOBinding.filetypes
)
class FiletypesTest(unittest.TestCase):
def test_python_source_files(self):
for extension in util.py_extensions:
with self.subTest(extension=extension):
self.assertTrue(
_extension_in_filetypes(extension)
)
def test_text_files(self):
self.assertTrue(_extension_in_filetypes('.txt'))
def test_all_files(self):
self.assertTrue(_extension_in_filetypes(''))
if __name__ == '__main__':
unittest.main(verbosity=2)