tests history init and history store with mock text classmethod def setupclasscls cls text mktext cls history historycls text def teardownself self text delete 1 0 end self history history def testinitself self assertisself history text self text self assertequalself history history self assertisnoneself history prefix self assertisnoneself history pointer self assertequalself history cyclic idleconf getoptionmain history cyclic 1 bool def teststoreshortself self history store a self assertequalself history history self history store a self assertequalself history history def teststoredupself self history storeline1 self assertequalself history history line1 self history storeline2 self assertequalself history history line1 line2 self history storeline1 self assertequalself history history line2 line1 def teststoreresetself self history prefix line1 self history pointer 0 self history storeline2 self assertisnoneself history prefix self assertisnoneself history pointer class textwrapper def initself master self text tktextmastermaster self bell false def getattrself name return getattrself text name def bellself self bell true class fetchtestunittest testcase classmethod def setupclasscls requires gui cls root tk tk cls root withdraw def setupself self text text textwrapperself root text insert 1 0 text markset iomark 1 4 text markgravity iomark left self history historytext self history history line1 line2 classmethod def teardownclasscls cls root destroy del cls root def fetchtestself reverse line prefix index bellfalse perform one fetch as invoked by altn or altp test the result the line test is the most important the last two are diagnostic of fetch internals history self history history fetchreverse equal self assertequal equalself text get iomark end1c line equalself text bell bell if bell self text bell false equalhistory prefix prefix equalhistory pointer index equalself text compareinsert end1c 1 def testfetchprevcyclicself prefix test self fetchtest testtrue line2 prefix 1 testtrue line1 prefix 0 testtrue prefix none none belltrue def testfetchnextcyclicself prefix test self fetchtest testfalse line1 prefix 0 testfalse line2 prefix 1 testfalse prefix none none belltrue prefix a tests skip line2 which starts with b def testfetchprevprefixself prefix a self text insert iomark prefix self fetchtesttrue line1 prefix 0 self fetchtesttrue prefix none none belltrue def testfetchnextprefixself prefix a self text insert iomark prefix self fetchtestfalse line1 prefix 0 self fetchtestfalse prefix none none belltrue def testfetchprevnoncyclicself prefix self history cyclic false test self fetchtest testtrue line2 prefix 1 testtrue line1 prefix 0 testtrue line1 prefix 0 belltrue def testfetchnextnoncyclicself prefix self history cyclic false test self fetchtest testfalse prefix none none belltrue testtrue line2 prefix 1 testfalse prefix none none belltrue testfalse prefix none none belltrue def testfetchcursormoveself move cursor after fetch self history fetchreversetrue initialization self text markset insert iomark self fetchtesttrue line2 none none belltrue def testfetcheditself edit after fetch self history fetchreversetrue initialization self text delete iomark insert self text insert iomark a self fetchtesttrue line1 a 0 prefix is reset def testhistoryprevnextself minimally test functions bound to events self history historyprev dummy event self assertequalself history pointer 1 self history historynext dummy event self assertequalself history pointer none if name main unittest mainverbosity2 exit2 tests history __init__ and history store with mock text test history fetch with wrapped tk text perform one fetch as invoked by alt n or alt p test the result the line test is the most important the last two are diagnostic of fetch internals prefix a tests skip line2 which starts with b move cursor after fetch initialization edit after fetch initialization prefix is reset minimally test functions bound to events
" Test history, coverage 100%."

from idlelib.history import History
import unittest
from test.support import requires

import tkinter as tk
from tkinter import Text as tkText
from idlelib.idle_test.mock_tk import Text as mkText
from idlelib.config import idleConf

line1 = 'a = 7'
line2 = 'b = a'


class StoreTest(unittest.TestCase):
    

    @classmethod
    def setUpClass(cls):
        cls.text = mkText()
        cls.history = History(cls.text)

    def tearDown(self):
        self.text.delete('1.0', 'end')
        self.history.history = []

    def test_init(self):
        self.assertIs(self.history.text, self.text)
        self.assertEqual(self.history.history, [])
        self.assertIsNone(self.history.prefix)
        self.assertIsNone(self.history.pointer)
        self.assertEqual(self.history.cyclic,
                idleConf.GetOption("main", "History",  "cyclic", 1, "bool"))

    def test_store_short(self):
        self.history.store('a')
        self.assertEqual(self.history.history, [])
        self.history.store('  a  ')
        self.assertEqual(self.history.history, [])

    def test_store_dup(self):
        self.history.store(line1)
        self.assertEqual(self.history.history, [line1])
        self.history.store(line2)
        self.assertEqual(self.history.history, [line1, line2])
        self.history.store(line1)
        self.assertEqual(self.history.history, [line2, line1])

    def test_store_reset(self):
        self.history.prefix = line1
        self.history.pointer = 0
        self.history.store(line2)
        self.assertIsNone(self.history.prefix)
        self.assertIsNone(self.history.pointer)


class TextWrapper:
    def __init__(self, master):
        self.text = tkText(master=master)
        self._bell = False
    def __getattr__(self, name):
        return getattr(self.text, name)
    def bell(self):
        self._bell = True


class FetchTest(unittest.TestCase):
    
    @classmethod
    def setUpClass(cls):
        requires('gui')
        cls.root = tk.Tk()
        cls.root.withdraw()

    def setUp(self):
        self.text = text = TextWrapper(self.root)
        text.insert('1.0', ">>> ")
        text.mark_set('iomark', '1.4')
        text.mark_gravity('iomark', 'left')
        self.history = History(text)
        self.history.history = [line1, line2]

    @classmethod
    def tearDownClass(cls):
        cls.root.destroy()
        del cls.root

    def fetch_test(self, reverse, line, prefix, index, *, bell=False):
        
        
        
        History = self.history
        History.fetch(reverse)

        Equal = self.assertEqual
        Equal(self.text.get('iomark', 'end-1c'), line)
        Equal(self.text._bell, bell)
        if bell:
            self.text._bell = False
        Equal(History.prefix, prefix)
        Equal(History.pointer, index)
        Equal(self.text.compare("insert", '==', "end-1c"), 1)

    def test_fetch_prev_cyclic(self):
        prefix = ''
        test = self.fetch_test
        test(True, line2, prefix, 1)
        test(True, line1, prefix, 0)
        test(True, prefix, None, None, bell=True)

    def test_fetch_next_cyclic(self):
        prefix = ''
        test  = self.fetch_test
        test(False, line1, prefix, 0)
        test(False, line2, prefix, 1)
        test(False, prefix, None, None, bell=True)

    
    def test_fetch_prev_prefix(self):
        prefix = 'a'
        self.text.insert('iomark', prefix)
        self.fetch_test(True, line1, prefix, 0)
        self.fetch_test(True, prefix, None, None, bell=True)

    def test_fetch_next_prefix(self):
        prefix = 'a'
        self.text.insert('iomark', prefix)
        self.fetch_test(False, line1, prefix, 0)
        self.fetch_test(False, prefix, None, None, bell=True)

    def test_fetch_prev_noncyclic(self):
        prefix = ''
        self.history.cyclic = False
        test = self.fetch_test
        test(True, line2, prefix, 1)
        test(True, line1, prefix, 0)
        test(True, line1, prefix, 0, bell=True)

    def test_fetch_next_noncyclic(self):
        prefix = ''
        self.history.cyclic = False
        test  = self.fetch_test
        test(False, prefix, None, None, bell=True)
        test(True, line2, prefix, 1)
        test(False, prefix, None, None, bell=True)
        test(False, prefix, None, None, bell=True)

    def test_fetch_cursor_move(self):
        
        self.history.fetch(reverse=True)  
        self.text.mark_set('insert', 'iomark')
        self.fetch_test(True, line2, None, None, bell=True)

    def test_fetch_edit(self):
        
        self.history.fetch(reverse=True)  
        self.text.delete('iomark', 'insert', )
        self.text.insert('iomark', 'a =')
        self.fetch_test(True, line1, 'a =', 0)  

    def test_history_prev_next(self):
        
        self.history.history_prev('dummy event')
        self.assertEqual(self.history.pointer, 1)
        self.history.history_next('dummy event')
        self.assertEqual(self.history.pointer, None)


if __name__ == '__main__':
    unittest.main(verbosity=2, exit=2)