Commit ea3dc802 authored by Terry Jan Reedy's avatar Terry Jan Reedy Committed by GitHub

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

Part 2 of 3.  Continues PR #7689, changeset ee5ef309.
Edit and add tests for 18 modules, help_about to replace and run.
parent 5092439c
...@@ -199,7 +199,8 @@ class AboutDialog(Toplevel): ...@@ -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)
...@@ -308,5 +308,5 @@ class HyperParser: ...@@ -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)
'''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):
......
" 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: ...@@ -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.
''' '''
......
"""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): ...@@ -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)
import unittest "Test , coverage 16%."
import io
from idlelib.run import PseudoInputFile, PseudoOutputFile
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 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) from idlelib import iomenu
self.assertEqual(shell.written, []) import unittest
self.assertRaises(TypeError, f.write, b'test') from test.support import requires
self.assertRaises(TypeError, f.write, 123) from tkinter import Tk
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.write, 'test', 'spam') from idlelib.editor import EditorWindow
self.assertEqual(shell.written, [])
def test_writelines(self): class IOBindigTest(unittest.TestCase):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8') @classmethod
f.writelines([]) def setUpClass(cls):
self.assertEqual(shell.written, []) requires('gui')
shell.reset() cls.root = Tk()
f.writelines(['one\n', 'two']) cls.root.withdraw()
self.assertEqual(shell.written, cls.editwin = EditorWindow(root=cls.root)
[('one\n', 'stdout'), ('two', 'stdout')])
shell.reset() @classmethod
f.writelines(['on\xe8\n', 'tw\xf2']) def tearDownClass(cls):
self.assertEqual(shell.written, cls.editwin._close()
[('on\xe8\n', 'stdout'), ('tw\xf2', 'stdout')]) del cls.editwin
shell.reset() cls.root.update_idletasks()
for id in cls.root.tk.call('after', 'info'):
f.writelines([S('t\xe8st')]) cls.root.after_cancel(id) # Need for EditorWindow.
self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) cls.root.destroy()
self.assertEqual(type(shell.written[0][0]), str) del cls.root
shell.reset()
def test_init(self):
self.assertRaises(TypeError, f.writelines) io = iomenu.IOBinding(self.editwin)
self.assertEqual(shell.written, []) self.assertIs(io.editwin, self.editwin)
self.assertRaises(TypeError, f.writelines, 123) io.close
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__':
......
'''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
......
"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)
"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)
""" 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
......
# 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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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
......
'''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')
......
""" 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
......
'''Test percolator.py.''' "Test percolator, coverage 100%."
from test.support import requires
requires('gui')
from idlelib.percolator import Percolator, Delegator
import unittest import unittest
from test.support import requires
requires('gui')
from tkinter import Text, Tk, END from tkinter import Text, Tk, END
from idlelib.percolator import Percolator, Delegator
class MyFilter(Delegator): class MyFilter(Delegator):
......
"""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):
......
"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)
"""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. ...@@ -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 idlelib import query
import unittest
from test.support import requires from test.support import requires
import sys
from tkinter import Tk from tkinter import Tk
import unittest
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
......
'''Test idlelib.redirector. "Test redirector, coverage 100%."
100% coverage from idlelib.redirector import WidgetRedirector
'''
from test.support import requires
import unittest import unittest
from idlelib.idle_test.mock_idle import Func from test.support import requires
from tkinter import Tk, Text, TclError from tkinter import Tk, Text, TclError
from idlelib.redirector import WidgetRedirector from idlelib.idle_test.mock_idle import Func
class InitCloseTest(unittest.TestCase): class InitCloseTest(unittest.TestCase):
......
"""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')
from tkinter import Tk, Text
import unittest
from unittest.mock import Mock from unittest.mock import Mock
from tkinter import Tk, Text
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
......
"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): ...@@ -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): ...@@ -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)
...@@ -567,8 +567,8 @@ def _io_binding(parent): # htest # ...@@ -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)
...@@ -36,7 +36,8 @@ menudefs = [ ...@@ -36,7 +36,8 @@ menudefs = [
None, None,
('_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,9 +57,9 @@ menudefs = [ ...@@ -56,9 +57,9 @@ 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>>'),
('Comment _Out Region', '<<comment-region>>'), ('Comment _Out Region', '<<comment-region>>'),
...@@ -70,30 +71,36 @@ menudefs = [ ...@@ -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'): ...@@ -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)
...@@ -441,5 +441,8 @@ def _multi_call(parent): # htest # ...@@ -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)
...@@ -190,6 +190,5 @@ def get_comment_header(line): ...@@ -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)
...@@ -179,5 +179,5 @@ ParenMatch.reload() ...@@ -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)
...@@ -96,9 +96,8 @@ def _percolator(parent): # htest # ...@@ -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)
...@@ -594,6 +594,6 @@ class Parser: ...@@ -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)
...@@ -301,8 +301,8 @@ class HelpSource(Query): ...@@ -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)
...@@ -167,9 +167,8 @@ def _widget_redirector(parent): # htest # ...@@ -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)
...@@ -235,9 +235,8 @@ def _replace_dialog(parent): # htest # ...@@ -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)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment