bpo-33855: More edits and new minimal tests for IDLE (GH-7761)

Part 2 of 3.  Continues PR #7689, changeset ee5ef30.
Edit and add tests for 18 modules, help_about to replace and run.
This commit is contained in:
Terry Jan Reedy 2018-06-18 04:47:59 -04:00 committed by GitHub
parent 5092439c2c
commit ea3dc8029a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 480 additions and 335 deletions

View file

@ -199,7 +199,8 @@ class AboutDialog(Toplevel):
if __name__ == '__main__': if __name__ == '__main__':
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_help_about', verbosity=2, exit=False) main('idlelib.idle_test.test_help_about', verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(AboutDialog) run(AboutDialog)

View file

@ -308,5 +308,5 @@ class HyperParser:
if __name__ == '__main__': if __name__ == '__main__':
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_hyperparser', verbosity=2) main('idlelib.idle_test.test_hyperparser', verbosity=2)

View file

@ -1,18 +1,19 @@
'''Test idlelib.help_about. """Test help_about, coverage 100%.
help_about.build_bits branches on sys.platform='darwin'.
'100% combines coverage on Mac and others.
"""
Coverage: 100% from idlelib import help_about
''' import unittest
from test.support import requires, findfile from test.support import requires, findfile
from tkinter import Tk, TclError from tkinter import Tk, TclError
import unittest
from unittest import mock
from idlelib.idle_test.mock_idle import Func from idlelib.idle_test.mock_idle import Func
from idlelib.idle_test.mock_tk import Mbox_func from idlelib.idle_test.mock_tk import Mbox_func
from idlelib.help_about import AboutDialog as About
from idlelib import help_about
from idlelib import textview from idlelib import textview
import os.path import os.path
from platform import python_version, architecture from platform import python_version
About = help_about.AboutDialog
class LiveDialogTest(unittest.TestCase): class LiveDialogTest(unittest.TestCase):

View file

@ -1,15 +1,18 @@
" Test history, coverage 100%."
from idlelib.history import History
import unittest import unittest
from test.support import requires from test.support import requires
import tkinter as tk import tkinter as tk
from tkinter import Text as tkText from tkinter import Text as tkText
from idlelib.idle_test.mock_tk import Text as mkText from idlelib.idle_test.mock_tk import Text as mkText
from idlelib.history import History
from idlelib.config import idleConf from idlelib.config import idleConf
line1 = 'a = 7' line1 = 'a = 7'
line2 = 'b = a' line2 = 'b = a'
class StoreTest(unittest.TestCase): class StoreTest(unittest.TestCase):
'''Tests History.__init__ and History.store with mock Text''' '''Tests History.__init__ and History.store with mock Text'''
@ -61,6 +64,7 @@ class TextWrapper:
def bell(self): def bell(self):
self._bell = True self._bell = True
class FetchTest(unittest.TestCase): class FetchTest(unittest.TestCase):
'''Test History.fetch with wrapped tk.Text. '''Test History.fetch with wrapped tk.Text.
''' '''

View file

@ -1,9 +1,10 @@
"""Unittest for idlelib.hyperparser.py.""" "Test hyperparser, coverage 98%."
from idlelib.hyperparser import HyperParser
import unittest import unittest
from test.support import requires from test.support import requires
from tkinter import Tk, Text from tkinter import Tk, Text
from idlelib.editor import EditorWindow from idlelib.editor import EditorWindow
from idlelib.hyperparser import HyperParser
class DummyEditwin: class DummyEditwin:
def __init__(self, text): def __init__(self, text):
@ -270,5 +271,6 @@ class HyperParserTest(unittest.TestCase):
self.assertEqual(eat_id('2' + 'a' * (length - 1), 0, length), 0) self.assertEqual(eat_id('2' + 'a' * (length - 1), 0, length), 0)
self.assertEqual(eat_id('2' + 'é' * (length - 1), 0, length), 0) self.assertEqual(eat_id('2' + 'é' * (length - 1), 0, length), 0)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(verbosity=2) unittest.main(verbosity=2)

View file

@ -1,233 +1,36 @@
"Test , coverage 16%."
from idlelib import iomenu
import unittest import unittest
import io from test.support import requires
from tkinter import Tk
from idlelib.run import PseudoInputFile, PseudoOutputFile from idlelib.editor import EditorWindow
class S(str): class IOBindigTest(unittest.TestCase):
def __str__(self):
return '%s:str' % type(self).__name__
def __unicode__(self):
return '%s:unicode' % type(self).__name__
def __len__(self):
return 3
def __iter__(self):
return iter('abc')
def __getitem__(self, *args):
return '%s:item' % type(self).__name__
def __getslice__(self, *args):
return '%s:slice' % type(self).__name__
class MockShell: @classmethod
def __init__(self): def setUpClass(cls):
self.reset() requires('gui')
cls.root = Tk()
cls.root.withdraw()
cls.editwin = EditorWindow(root=cls.root)
def write(self, *args): @classmethod
self.written.append(args) def tearDownClass(cls):
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 readline(self): def test_init(self):
return self.lines.pop() io = iomenu.IOBinding(self.editwin)
self.assertIs(io.editwin, self.editwin)
def close(self): io.close
pass
def reset(self):
self.written = []
def push(self, lines):
self.lines = list(lines)[::-1]
class PseudeOutputFilesTest(unittest.TestCase):
def test_misc(self):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertIsInstance(f, io.TextIOBase)
self.assertEqual(f.encoding, 'utf-8')
self.assertIsNone(f.errors)
self.assertIsNone(f.newlines)
self.assertEqual(f.name, '<stdout>')
self.assertFalse(f.closed)
self.assertTrue(f.isatty())
self.assertFalse(f.readable())
self.assertTrue(f.writable())
self.assertFalse(f.seekable())
def test_unsupported(self):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertRaises(OSError, f.fileno)
self.assertRaises(OSError, f.tell)
self.assertRaises(OSError, f.seek, 0)
self.assertRaises(OSError, f.read, 0)
self.assertRaises(OSError, f.readline, 0)
def test_write(self):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8')
f.write('test')
self.assertEqual(shell.written, [('test', 'stdout')])
shell.reset()
f.write('t\xe8st')
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
shell.reset()
f.write(S('t\xe8st'))
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
self.assertEqual(type(shell.written[0][0]), str)
shell.reset()
self.assertRaises(TypeError, f.write)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.write, b'test')
self.assertRaises(TypeError, f.write, 123)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.write, 'test', 'spam')
self.assertEqual(shell.written, [])
def test_writelines(self):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8')
f.writelines([])
self.assertEqual(shell.written, [])
shell.reset()
f.writelines(['one\n', 'two'])
self.assertEqual(shell.written,
[('one\n', 'stdout'), ('two', 'stdout')])
shell.reset()
f.writelines(['on\xe8\n', 'tw\xf2'])
self.assertEqual(shell.written,
[('on\xe8\n', 'stdout'), ('tw\xf2', 'stdout')])
shell.reset()
f.writelines([S('t\xe8st')])
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
self.assertEqual(type(shell.written[0][0]), str)
shell.reset()
self.assertRaises(TypeError, f.writelines)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, 123)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, [b'test'])
self.assertRaises(TypeError, f.writelines, [123])
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, [], [])
self.assertEqual(shell.written, [])
def test_close(self):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertFalse(f.closed)
f.write('test')
f.close()
self.assertTrue(f.closed)
self.assertRaises(ValueError, f.write, 'x')
self.assertEqual(shell.written, [('test', 'stdout')])
f.close()
self.assertRaises(TypeError, f.close, 1)
class PseudeInputFilesTest(unittest.TestCase):
def test_misc(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
self.assertIsInstance(f, io.TextIOBase)
self.assertEqual(f.encoding, 'utf-8')
self.assertIsNone(f.errors)
self.assertIsNone(f.newlines)
self.assertEqual(f.name, '<stdin>')
self.assertFalse(f.closed)
self.assertTrue(f.isatty())
self.assertTrue(f.readable())
self.assertFalse(f.writable())
self.assertFalse(f.seekable())
def test_unsupported(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
self.assertRaises(OSError, f.fileno)
self.assertRaises(OSError, f.tell)
self.assertRaises(OSError, f.seek, 0)
self.assertRaises(OSError, f.write, 'x')
self.assertRaises(OSError, f.writelines, ['x'])
def test_read(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(), 'one\ntwo\n')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(-1), 'one\ntwo\n')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(None), 'one\ntwo\n')
shell.push(['one\n', 'two\n', 'three\n', ''])
self.assertEqual(f.read(2), 'on')
self.assertEqual(f.read(3), 'e\nt')
self.assertEqual(f.read(10), 'wo\nthree\n')
shell.push(['one\n', 'two\n'])
self.assertEqual(f.read(0), '')
self.assertRaises(TypeError, f.read, 1.5)
self.assertRaises(TypeError, f.read, '1')
self.assertRaises(TypeError, f.read, 1, 1)
def test_readline(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', 'three\n', 'four\n'])
self.assertEqual(f.readline(), 'one\n')
self.assertEqual(f.readline(-1), 'two\n')
self.assertEqual(f.readline(None), 'three\n')
shell.push(['one\ntwo\n'])
self.assertEqual(f.readline(), 'one\n')
self.assertEqual(f.readline(), 'two\n')
shell.push(['one', 'two', 'three'])
self.assertEqual(f.readline(), 'one')
self.assertEqual(f.readline(), 'two')
shell.push(['one\n', 'two\n', 'three\n'])
self.assertEqual(f.readline(2), 'on')
self.assertEqual(f.readline(1), 'e')
self.assertEqual(f.readline(1), '\n')
self.assertEqual(f.readline(10), 'two\n')
shell.push(['one\n', 'two\n'])
self.assertEqual(f.readline(0), '')
self.assertRaises(TypeError, f.readlines, 1.5)
self.assertRaises(TypeError, f.readlines, '1')
self.assertRaises(TypeError, f.readlines, 1, 1)
def test_readlines(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(-1), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(None), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(0), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(3), ['one\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(4), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertRaises(TypeError, f.readlines, 1.5)
self.assertRaises(TypeError, f.readlines, '1')
self.assertRaises(TypeError, f.readlines, 1, 1)
def test_close(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertFalse(f.closed)
self.assertEqual(f.readline(), 'one\n')
f.close()
self.assertFalse(f.closed)
self.assertEqual(f.readline(), 'two\n')
self.assertRaises(TypeError, f.close, 1)
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -1,11 +1,9 @@
'''Test idlelib.macosx.py. "Test macosx, coverage 45% on Windows."
Coverage: 71% on Windows.
'''
from idlelib import macosx from idlelib import macosx
import unittest
from test.support import requires from test.support import requires
import tkinter as tk import tkinter as tk
import unittest
import unittest.mock as mock import unittest.mock as mock
from idlelib.filelist import FileList from idlelib.filelist import FileList

View file

@ -0,0 +1,21 @@
"Test mainmenu, coverage 100%."
# Reported as 88%; mocking turtledemo absence would have no point.
from idlelib import mainmenu
import unittest
class MainMenuTest(unittest.TestCase):
def test_menudefs(self):
actual = [item[0] for item in mainmenu.menudefs]
expect = ['file', 'edit', 'format', 'run', 'shell',
'debug', 'options', 'windows', 'help']
self.assertEqual(actual, expect)
def test_default_keydefs(self):
self.assertGreaterEqual(len(mainmenu.default_keydefs), 50)
if __name__ == '__main__':
unittest.main(verbosity=2)

View file

@ -0,0 +1,40 @@
"Test multicall, coverage 33%."
from idlelib import multicall
import unittest
from test.support import requires
from tkinter import Tk, Text
class MultiCallTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
cls.mc = multicall.MultiCallCreator(Text)
@classmethod
def tearDownClass(cls):
del cls.mc
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_creator(self):
mc = self.mc
self.assertIs(multicall._multicall_dict[Text], mc)
self.assertTrue(issubclass(mc, Text))
mc2 = multicall.MultiCallCreator(Text)
self.assertIs(mc, mc2)
def test_init(self):
mctext = self.mc(self.root)
self.assertIsInstance(mctext._MultiCall__binders, list)
if __name__ == '__main__':
unittest.main(verbosity=2)

View file

@ -1,12 +1,11 @@
""" Test idlelib.outwin. "Test outwin, coverage 76%."
"""
from idlelib import outwin
import unittest import unittest
from test.support import requires
from tkinter import Tk, Text from tkinter import Tk, Text
from idlelib.idle_test.mock_tk import Mbox_func from idlelib.idle_test.mock_tk import Mbox_func
from idlelib.idle_test.mock_idle import Func from idlelib.idle_test.mock_idle import Func
from idlelib import outwin
from test.support import requires
from unittest import mock from unittest import mock

View file

@ -1,9 +1,10 @@
# Test the functions and main class method of paragraph.py "Test paragraph, coverage 76%."
from idlelib import paragraph as pg
import unittest import unittest
from idlelib import paragraph as fp
from idlelib.editor import EditorWindow
from tkinter import Tk, Text
from test.support import requires from test.support import requires
from tkinter import Tk, Text
from idlelib.editor import EditorWindow
class Is_Get_Test(unittest.TestCase): class Is_Get_Test(unittest.TestCase):
@ -15,26 +16,26 @@ class Is_Get_Test(unittest.TestCase):
leadingws_nocomment = ' This is not a comment' leadingws_nocomment = ' This is not a comment'
def test_is_all_white(self): def test_is_all_white(self):
self.assertTrue(fp.is_all_white('')) self.assertTrue(pg.is_all_white(''))
self.assertTrue(fp.is_all_white('\t\n\r\f\v')) self.assertTrue(pg.is_all_white('\t\n\r\f\v'))
self.assertFalse(fp.is_all_white(self.test_comment)) self.assertFalse(pg.is_all_white(self.test_comment))
def test_get_indent(self): def test_get_indent(self):
Equal = self.assertEqual Equal = self.assertEqual
Equal(fp.get_indent(self.test_comment), '') Equal(pg.get_indent(self.test_comment), '')
Equal(fp.get_indent(self.trailingws_comment), '') Equal(pg.get_indent(self.trailingws_comment), '')
Equal(fp.get_indent(self.leadingws_comment), ' ') Equal(pg.get_indent(self.leadingws_comment), ' ')
Equal(fp.get_indent(self.leadingws_nocomment), ' ') Equal(pg.get_indent(self.leadingws_nocomment), ' ')
def test_get_comment_header(self): def test_get_comment_header(self):
Equal = self.assertEqual Equal = self.assertEqual
# Test comment strings # Test comment strings
Equal(fp.get_comment_header(self.test_comment), '#') Equal(pg.get_comment_header(self.test_comment), '#')
Equal(fp.get_comment_header(self.trailingws_comment), '#') Equal(pg.get_comment_header(self.trailingws_comment), '#')
Equal(fp.get_comment_header(self.leadingws_comment), ' #') Equal(pg.get_comment_header(self.leadingws_comment), ' #')
# Test non-comment strings # Test non-comment strings
Equal(fp.get_comment_header(self.leadingws_nocomment), ' ') Equal(pg.get_comment_header(self.leadingws_nocomment), ' ')
Equal(fp.get_comment_header(self.test_nocomment), '') Equal(pg.get_comment_header(self.test_nocomment), '')
class FindTest(unittest.TestCase): class FindTest(unittest.TestCase):
@ -62,7 +63,7 @@ class FindTest(unittest.TestCase):
linelength = int(text.index("%d.end" % line).split('.')[1]) linelength = int(text.index("%d.end" % line).split('.')[1])
for col in (0, linelength//2, linelength): for col in (0, linelength//2, linelength):
tempindex = "%d.%d" % (line, col) tempindex = "%d.%d" % (line, col)
self.assertEqual(fp.find_paragraph(text, tempindex), expected) self.assertEqual(pg.find_paragraph(text, tempindex), expected)
text.delete('1.0', 'end') text.delete('1.0', 'end')
def test_find_comment(self): def test_find_comment(self):
@ -161,7 +162,7 @@ class ReformatFunctionTest(unittest.TestCase):
def test_reformat_paragraph(self): def test_reformat_paragraph(self):
Equal = self.assertEqual Equal = self.assertEqual
reform = fp.reformat_paragraph reform = pg.reformat_paragraph
hw = "O hello world" hw = "O hello world"
Equal(reform(' ', 1), ' ') Equal(reform(' ', 1), ' ')
Equal(reform("Hello world", 20), "Hello world") Equal(reform("Hello world", 20), "Hello world")
@ -192,7 +193,7 @@ class ReformatCommentTest(unittest.TestCase):
test_string = ( test_string = (
" \"\"\"this is a test of a reformat for a triple quoted string" " \"\"\"this is a test of a reformat for a triple quoted string"
" will it reformat to less than 70 characters for me?\"\"\"") " will it reformat to less than 70 characters for me?\"\"\"")
result = fp.reformat_comment(test_string, 70, " ") result = pg.reformat_comment(test_string, 70, " ")
expected = ( expected = (
" \"\"\"this is a test of a reformat for a triple quoted string will it\n" " \"\"\"this is a test of a reformat for a triple quoted string will it\n"
" reformat to less than 70 characters for me?\"\"\"") " reformat to less than 70 characters for me?\"\"\"")
@ -201,7 +202,7 @@ class ReformatCommentTest(unittest.TestCase):
test_comment = ( test_comment = (
"# this is a test of a reformat for a triple quoted string will " "# this is a test of a reformat for a triple quoted string will "
"it reformat to less than 70 characters for me?") "it reformat to less than 70 characters for me?")
result = fp.reformat_comment(test_comment, 70, "#") result = pg.reformat_comment(test_comment, 70, "#")
expected = ( expected = (
"# this is a test of a reformat for a triple quoted string will it\n" "# this is a test of a reformat for a triple quoted string will it\n"
"# reformat to less than 70 characters for me?") "# reformat to less than 70 characters for me?")
@ -210,7 +211,7 @@ class ReformatCommentTest(unittest.TestCase):
class FormatClassTest(unittest.TestCase): class FormatClassTest(unittest.TestCase):
def test_init_close(self): def test_init_close(self):
instance = fp.FormatParagraph('editor') instance = pg.FormatParagraph('editor')
self.assertEqual(instance.editwin, 'editor') self.assertEqual(instance.editwin, 'editor')
instance.close() instance.close()
self.assertEqual(instance.editwin, None) self.assertEqual(instance.editwin, None)
@ -269,14 +270,16 @@ class FormatEventTest(unittest.TestCase):
def setUpClass(cls): def setUpClass(cls):
requires('gui') requires('gui')
cls.root = Tk() cls.root = Tk()
cls.root.withdraw()
editor = Editor(root=cls.root) editor = Editor(root=cls.root)
cls.text = editor.text.text # Test code does not need the wrapper. cls.text = editor.text.text # Test code does not need the wrapper.
cls.formatter = fp.FormatParagraph(editor).format_paragraph_event cls.formatter = pg.FormatParagraph(editor).format_paragraph_event
# Sets the insert mark just after the re-wrapped and inserted text. # Sets the insert mark just after the re-wrapped and inserted text.
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):
del cls.text, cls.formatter del cls.text, cls.formatter
cls.root.update_idletasks()
cls.root.destroy() cls.root.destroy()
del cls.root del cls.root

View file

@ -1,8 +1,8 @@
'''Test idlelib.parenmatch. """Test parenmatch, coverage 91%.
This must currently be a gui test because ParenMatch methods use This must currently be a gui test because ParenMatch methods use
several text methods not defined on idlelib.idle_test.mock_tk.Text. several text methods not defined on idlelib.idle_test.mock_tk.Text.
''' """
from idlelib.parenmatch import ParenMatch from idlelib.parenmatch import ParenMatch
from test.support import requires from test.support import requires
requires('gui') requires('gui')

View file

@ -1,19 +1,17 @@
""" Test idlelib.pathbrowser. "Test pathbrowser, coverage 95%."
"""
from idlelib import pathbrowser
import unittest
from test.support import requires
from tkinter import Tk
import os.path import os.path
import pyclbr # for _modules import pyclbr # for _modules
import sys # for sys.path import sys # for sys.path
from tkinter import Tk
from test.support import requires
import unittest
from idlelib.idle_test.mock_idle import Func from idlelib.idle_test.mock_idle import Func
import idlelib # for __file__ import idlelib # for __file__
from idlelib import browser from idlelib import browser
from idlelib import pathbrowser
from idlelib.tree import TreeNode from idlelib.tree import TreeNode

View file

@ -1,10 +1,10 @@
'''Test percolator.py.''' "Test percolator, coverage 100%."
from idlelib.percolator import Percolator, Delegator
import unittest
from test.support import requires from test.support import requires
requires('gui') requires('gui')
import unittest
from tkinter import Text, Tk, END from tkinter import Text, Tk, END
from idlelib.percolator import Percolator, Delegator
class MyFilter(Delegator): class MyFilter(Delegator):

View file

@ -1,11 +1,8 @@
"""Unittest for idlelib.pyparse.py. "Test pyparse, coverage 96%."
Coverage: 97%
"""
from collections import namedtuple
import unittest
from idlelib import pyparse from idlelib import pyparse
import unittest
from collections import namedtuple
class ParseMapTest(unittest.TestCase): class ParseMapTest(unittest.TestCase):

View file

@ -0,0 +1,42 @@
"Test pyshell, coverage 12%."
# Plus coverage of test_warning. Was 20% with test_openshell.
from idlelib import pyshell
import unittest
from test.support import requires
from tkinter import Tk
class PyShellFileListTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
@classmethod
def tearDownClass(cls):
#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):
psfl = pyshell.PyShellFileList(self.root)
self.assertEqual(psfl.EditorWindow, pyshell.PyShellEditorWindow)
self.assertIsNone(psfl.pyshell)
# The following sometimes causes 'invalid command name "109734456recolorize"'.
# Uncommenting after_cancel above prevents this, but results in
# TclError: bad window path name ".!listedtoplevel.!frame.text"
# which is normally prevented by after_cancel.
## def test_openshell(self):
## pyshell.use_subprocess = False
## ps = pyshell.PyShellFileList(self.root).open_shell()
## self.assertIsInstance(ps, pyshell.PyShell)
if __name__ == '__main__':
unittest.main(verbosity=2)

View file

@ -1,4 +1,4 @@
"""Test idlelib.query. """Test query, coverage 91%).
Non-gui tests for Query, SectionName, ModuleName, and HelpSource use Non-gui tests for Query, SectionName, ModuleName, and HelpSource use
dummy versions that extract the non-gui methods and add other needed dummy versions that extract the non-gui methods and add other needed
@ -8,17 +8,15 @@ the subclass definition.
The appearance of the widgets is checked by the Query and The appearance of the widgets is checked by the Query and
HelpSource htests. These are run by running query.py. HelpSource htests. These are run by running query.py.
Coverage: 94% (100% for Query and SectionName).
6 of 8 missing are ModuleName exceptions I don't know how to trigger.
""" """
from test.support import requires from idlelib import query
import sys
from tkinter import Tk
import unittest import unittest
from test.support import requires
from tkinter import Tk
import sys
from unittest import mock from unittest import mock
from idlelib.idle_test.mock_tk import Var from idlelib.idle_test.mock_tk import Var
from idlelib import query
# NON-GUI TESTS # NON-GUI TESTS

View file

@ -1,12 +1,10 @@
'''Test idlelib.redirector. "Test redirector, coverage 100%."
100% coverage
'''
from test.support import requires
import unittest
from idlelib.idle_test.mock_idle import Func
from tkinter import Tk, Text, TclError
from idlelib.redirector import WidgetRedirector from idlelib.redirector import WidgetRedirector
import unittest
from test.support import requires
from tkinter import Tk, Text, TclError
from idlelib.idle_test.mock_idle import Func
class InitCloseTest(unittest.TestCase): class InitCloseTest(unittest.TestCase):

View file

@ -1,13 +1,14 @@
"""Unittest for idlelib.replace.py""" "Test replace, coverage 78%."
from idlelib.replace import ReplaceDialog
import unittest
from test.support import requires from test.support import requires
requires('gui') requires('gui')
import unittest
from unittest.mock import Mock
from tkinter import Tk, Text from tkinter import Tk, Text
from unittest.mock import Mock
from idlelib.idle_test.mock_tk import Mbox from idlelib.idle_test.mock_tk import Mbox
import idlelib.searchengine as se import idlelib.searchengine as se
from idlelib.replace import ReplaceDialog
orig_mbox = se.tkMessageBox orig_mbox = se.tkMessageBox
showerror = Mbox.showerror showerror = Mbox.showerror

View file

@ -1,11 +1,14 @@
"Test run, coverage 42%."
from idlelib import run
import unittest import unittest
from unittest import mock from unittest import mock
from test.support import captured_stderr from test.support import captured_stderr
import idlelib.run as idlerun
import io
class RunTest(unittest.TestCase): class RunTest(unittest.TestCase):
def test_print_exception_unhashable(self): def test_print_exception_unhashable(self):
class UnhashableException(Exception): class UnhashableException(Exception):
def __eq__(self, other): def __eq__(self, other):
@ -20,10 +23,10 @@ class RunTest(unittest.TestCase):
raise ex1 raise ex1
except UnhashableException: except UnhashableException:
with captured_stderr() as output: with captured_stderr() as output:
with mock.patch.object(idlerun, with mock.patch.object(run,
'cleanup_traceback') as ct: 'cleanup_traceback') as ct:
ct.side_effect = lambda t, e: t ct.side_effect = lambda t, e: t
idlerun.print_exception() run.print_exception()
tb = output.getvalue().strip().splitlines() tb = output.getvalue().strip().splitlines()
self.assertEqual(11, len(tb)) self.assertEqual(11, len(tb))
@ -31,5 +34,231 @@ class RunTest(unittest.TestCase):
self.assertIn('UnhashableException: ex1', tb[10]) self.assertIn('UnhashableException: ex1', tb[10])
# PseudoFile tests.
class S(str):
def __str__(self):
return '%s:str' % type(self).__name__
def __unicode__(self):
return '%s:unicode' % type(self).__name__
def __len__(self):
return 3
def __iter__(self):
return iter('abc')
def __getitem__(self, *args):
return '%s:item' % type(self).__name__
def __getslice__(self, *args):
return '%s:slice' % type(self).__name__
class MockShell:
def __init__(self):
self.reset()
def write(self, *args):
self.written.append(args)
def readline(self):
return self.lines.pop()
def close(self):
pass
def reset(self):
self.written = []
def push(self, lines):
self.lines = list(lines)[::-1]
class PseudeInputFilesTest(unittest.TestCase):
def test_misc(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
self.assertIsInstance(f, io.TextIOBase)
self.assertEqual(f.encoding, 'utf-8')
self.assertIsNone(f.errors)
self.assertIsNone(f.newlines)
self.assertEqual(f.name, '<stdin>')
self.assertFalse(f.closed)
self.assertTrue(f.isatty())
self.assertTrue(f.readable())
self.assertFalse(f.writable())
self.assertFalse(f.seekable())
def test_unsupported(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
self.assertRaises(OSError, f.fileno)
self.assertRaises(OSError, f.tell)
self.assertRaises(OSError, f.seek, 0)
self.assertRaises(OSError, f.write, 'x')
self.assertRaises(OSError, f.writelines, ['x'])
def test_read(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(), 'one\ntwo\n')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(-1), 'one\ntwo\n')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(None), 'one\ntwo\n')
shell.push(['one\n', 'two\n', 'three\n', ''])
self.assertEqual(f.read(2), 'on')
self.assertEqual(f.read(3), 'e\nt')
self.assertEqual(f.read(10), 'wo\nthree\n')
shell.push(['one\n', 'two\n'])
self.assertEqual(f.read(0), '')
self.assertRaises(TypeError, f.read, 1.5)
self.assertRaises(TypeError, f.read, '1')
self.assertRaises(TypeError, f.read, 1, 1)
def test_readline(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', 'three\n', 'four\n'])
self.assertEqual(f.readline(), 'one\n')
self.assertEqual(f.readline(-1), 'two\n')
self.assertEqual(f.readline(None), 'three\n')
shell.push(['one\ntwo\n'])
self.assertEqual(f.readline(), 'one\n')
self.assertEqual(f.readline(), 'two\n')
shell.push(['one', 'two', 'three'])
self.assertEqual(f.readline(), 'one')
self.assertEqual(f.readline(), 'two')
shell.push(['one\n', 'two\n', 'three\n'])
self.assertEqual(f.readline(2), 'on')
self.assertEqual(f.readline(1), 'e')
self.assertEqual(f.readline(1), '\n')
self.assertEqual(f.readline(10), 'two\n')
shell.push(['one\n', 'two\n'])
self.assertEqual(f.readline(0), '')
self.assertRaises(TypeError, f.readlines, 1.5)
self.assertRaises(TypeError, f.readlines, '1')
self.assertRaises(TypeError, f.readlines, 1, 1)
def test_readlines(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(-1), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(None), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(0), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(3), ['one\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(4), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertRaises(TypeError, f.readlines, 1.5)
self.assertRaises(TypeError, f.readlines, '1')
self.assertRaises(TypeError, f.readlines, 1, 1)
def test_close(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertFalse(f.closed)
self.assertEqual(f.readline(), 'one\n')
f.close()
self.assertFalse(f.closed)
self.assertEqual(f.readline(), 'two\n')
self.assertRaises(TypeError, f.close, 1)
class PseudeOutputFilesTest(unittest.TestCase):
def test_misc(self):
shell = MockShell()
f = run.PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertIsInstance(f, io.TextIOBase)
self.assertEqual(f.encoding, 'utf-8')
self.assertIsNone(f.errors)
self.assertIsNone(f.newlines)
self.assertEqual(f.name, '<stdout>')
self.assertFalse(f.closed)
self.assertTrue(f.isatty())
self.assertFalse(f.readable())
self.assertTrue(f.writable())
self.assertFalse(f.seekable())
def test_unsupported(self):
shell = MockShell()
f = run.PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertRaises(OSError, f.fileno)
self.assertRaises(OSError, f.tell)
self.assertRaises(OSError, f.seek, 0)
self.assertRaises(OSError, f.read, 0)
self.assertRaises(OSError, f.readline, 0)
def test_write(self):
shell = MockShell()
f = run.PseudoOutputFile(shell, 'stdout', 'utf-8')
f.write('test')
self.assertEqual(shell.written, [('test', 'stdout')])
shell.reset()
f.write('t\xe8st')
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
shell.reset()
f.write(S('t\xe8st'))
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
self.assertEqual(type(shell.written[0][0]), str)
shell.reset()
self.assertRaises(TypeError, f.write)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.write, b'test')
self.assertRaises(TypeError, f.write, 123)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.write, 'test', 'spam')
self.assertEqual(shell.written, [])
def test_writelines(self):
shell = MockShell()
f = run.PseudoOutputFile(shell, 'stdout', 'utf-8')
f.writelines([])
self.assertEqual(shell.written, [])
shell.reset()
f.writelines(['one\n', 'two'])
self.assertEqual(shell.written,
[('one\n', 'stdout'), ('two', 'stdout')])
shell.reset()
f.writelines(['on\xe8\n', 'tw\xf2'])
self.assertEqual(shell.written,
[('on\xe8\n', 'stdout'), ('tw\xf2', 'stdout')])
shell.reset()
f.writelines([S('t\xe8st')])
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
self.assertEqual(type(shell.written[0][0]), str)
shell.reset()
self.assertRaises(TypeError, f.writelines)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, 123)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, [b'test'])
self.assertRaises(TypeError, f.writelines, [123])
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, [], [])
self.assertEqual(shell.written, [])
def test_close(self):
shell = MockShell()
f = run.PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertFalse(f.closed)
f.write('test')
f.close()
self.assertTrue(f.closed)
self.assertRaises(ValueError, f.write, 'x')
self.assertEqual(shell.written, [('test', 'stdout')])
f.close()
self.assertRaises(TypeError, f.close, 1)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(verbosity=2) unittest.main(verbosity=2)

View file

@ -567,8 +567,8 @@ def _io_binding(parent): # htest #
IOBinding(editwin) IOBinding(editwin)
if __name__ == "__main__": if __name__ == "__main__":
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_iomenu', verbosity=2, exit=False) main('idlelib.idle_test.test_iomenu', verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(_io_binding) run(_io_binding)

View file

@ -37,6 +37,7 @@ menudefs = [
('_Close', '<<close-window>>'), ('_Close', '<<close-window>>'),
('E_xit', '<<close-all-windows>>'), ('E_xit', '<<close-all-windows>>'),
]), ]),
('edit', [ ('edit', [
('_Undo', '<<undo>>'), ('_Undo', '<<undo>>'),
('_Redo', '<<redo>>'), ('_Redo', '<<redo>>'),
@ -56,8 +57,8 @@ menudefs = [
('E_xpand Word', '<<expand-word>>'), ('E_xpand Word', '<<expand-word>>'),
('Show C_all Tip', '<<force-open-calltip>>'), ('Show C_all Tip', '<<force-open-calltip>>'),
('Show Surrounding P_arens', '<<flash-paren>>'), ('Show Surrounding P_arens', '<<flash-paren>>'),
]), ]),
('format', [ ('format', [
('_Indent Region', '<<indent-region>>'), ('_Indent Region', '<<indent-region>>'),
('_Dedent Region', '<<dedent-region>>'), ('_Dedent Region', '<<dedent-region>>'),
@ -70,30 +71,36 @@ menudefs = [
('F_ormat Paragraph', '<<format-paragraph>>'), ('F_ormat Paragraph', '<<format-paragraph>>'),
('S_trip Trailing Whitespace', '<<do-rstrip>>'), ('S_trip Trailing Whitespace', '<<do-rstrip>>'),
]), ]),
('run', [ ('run', [
('Python Shell', '<<open-python-shell>>'), ('Python Shell', '<<open-python-shell>>'),
('C_heck Module', '<<check-module>>'), ('C_heck Module', '<<check-module>>'),
('R_un Module', '<<run-module>>'), ('R_un Module', '<<run-module>>'),
]), ]),
('shell', [ ('shell', [
('_View Last Restart', '<<view-restart>>'), ('_View Last Restart', '<<view-restart>>'),
('_Restart Shell', '<<restart-shell>>'), ('_Restart Shell', '<<restart-shell>>'),
None, None,
('_Interrupt Execution', '<<interrupt-execution>>'), ('_Interrupt Execution', '<<interrupt-execution>>'),
]), ]),
('debug', [ ('debug', [
('_Go to File/Line', '<<goto-file-line>>'), ('_Go to File/Line', '<<goto-file-line>>'),
('!_Debugger', '<<toggle-debugger>>'), ('!_Debugger', '<<toggle-debugger>>'),
('_Stack Viewer', '<<open-stack-viewer>>'), ('_Stack Viewer', '<<open-stack-viewer>>'),
('!_Auto-open Stack Viewer', '<<toggle-jit-stack-viewer>>'), ('!_Auto-open Stack Viewer', '<<toggle-jit-stack-viewer>>'),
]), ]),
('options', [ ('options', [
('Configure _IDLE', '<<open-config-dialog>>'), ('Configure _IDLE', '<<open-config-dialog>>'),
('_Code Context', '<<toggle-code-context>>'), ('_Code Context', '<<toggle-code-context>>'),
]), ]),
('windows', [ ('windows', [
('Zoom Height', '<<zoom-height>>'), ('Zoom Height', '<<zoom-height>>'),
]), ]),
('help', [ ('help', [
('_About IDLE', '<<about-idle>>'), ('_About IDLE', '<<about-idle>>'),
None, None,
@ -106,3 +113,7 @@ if find_spec('turtledemo'):
menudefs[-1][1].append(('Turtle Demo', '<<open-turtle-demo>>')) menudefs[-1][1].append(('Turtle Demo', '<<open-turtle-demo>>'))
default_keydefs = idleConf.GetCurrentKeySet() default_keydefs = idleConf.GetCurrentKeySet()
if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_mainmenu', verbosity=2)

View file

@ -441,5 +441,8 @@ def _multi_call(parent): # htest #
bindseq("<Leave>") bindseq("<Leave>")
if __name__ == "__main__": if __name__ == "__main__":
from unittest import main
main('idlelib.idle_test.test_mainmenu', verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(_multi_call) run(_multi_call)

View file

@ -190,6 +190,5 @@ def get_comment_header(line):
if __name__ == "__main__": if __name__ == "__main__":
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_paragraph', main('idlelib.idle_test.test_paragraph', verbosity=2, exit=False)
verbosity=2, exit=False)

View file

@ -179,5 +179,5 @@ ParenMatch.reload()
if __name__ == '__main__': if __name__ == '__main__':
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_parenmatch', verbosity=2) main('idlelib.idle_test.test_parenmatch', verbosity=2)

View file

@ -96,9 +96,8 @@ def _percolator(parent): # htest #
cb2.pack() cb2.pack()
if __name__ == "__main__": if __name__ == "__main__":
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_percolator', verbosity=2, main('idlelib.idle_test.test_percolator', verbosity=2, exit=False)
exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(_percolator) run(_percolator)

View file

@ -594,6 +594,6 @@ class Parser:
return self.stmt_bracketing return self.stmt_bracketing
if __name__ == '__main__': #pragma: nocover if __name__ == '__main__':
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_pyparse', verbosity=2) main('idlelib.idle_test.test_pyparse', verbosity=2)

View file

@ -301,8 +301,8 @@ class HelpSource(Query):
if __name__ == '__main__': if __name__ == '__main__':
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_query', verbosity=2, exit=False) main('idlelib.idle_test.test_query', verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(Query, HelpSource) run(Query, HelpSource)

View file

@ -167,9 +167,8 @@ def _widget_redirector(parent): # htest #
original_insert = redir.register("insert", my_insert) original_insert = redir.register("insert", my_insert)
if __name__ == "__main__": if __name__ == "__main__":
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_redirector', main('idlelib.idle_test.test_redirector', verbosity=2, exit=False)
verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(_widget_redirector) run(_widget_redirector)

View file

@ -235,9 +235,8 @@ def _replace_dialog(parent): # htest #
button.pack() button.pack()
if __name__ == '__main__': if __name__ == '__main__':
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_replace', main('idlelib.idle_test.test_replace', verbosity=2, exit=False)
verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(_replace_dialog) run(_replace_dialog)