17db96d56Sopenharmony_ciimport unittest
27db96d56Sopenharmony_ciimport tkinter
37db96d56Sopenharmony_cifrom tkinter import ttk, TclError
47db96d56Sopenharmony_cifrom test.support import requires, gc_collect
57db96d56Sopenharmony_ciimport sys
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_cifrom test.test_ttk_textonly import MockTclObj
87db96d56Sopenharmony_cifrom tkinter.test.support import (AbstractTkTest, tcl_version, get_tk_patchlevel,
97db96d56Sopenharmony_ci                                  simulate_mouse_click, AbstractDefaultRootTest)
107db96d56Sopenharmony_cifrom tkinter.test.widget_tests import (add_standard_options,
117db96d56Sopenharmony_ci    AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests,
127db96d56Sopenharmony_ci    setUpModule)
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_cirequires('gui')
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ciclass StandardTtkOptionsTests(StandardOptionsTests):
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci    def test_configure_class(self):
207db96d56Sopenharmony_ci        widget = self.create()
217db96d56Sopenharmony_ci        self.assertEqual(widget['class'], '')
227db96d56Sopenharmony_ci        errmsg='attempt to change read-only option'
237db96d56Sopenharmony_ci        if get_tk_patchlevel() < (8, 6, 0, 'beta', 3):
247db96d56Sopenharmony_ci            errmsg='Attempt to change read-only option'
257db96d56Sopenharmony_ci        self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg)
267db96d56Sopenharmony_ci        widget2 = self.create(class_='Foo')
277db96d56Sopenharmony_ci        self.assertEqual(widget2['class'], 'Foo')
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ci    def test_configure_padding(self):
307db96d56Sopenharmony_ci        widget = self.create()
317db96d56Sopenharmony_ci        self.checkParam(widget, 'padding', 0, expected=('0',))
327db96d56Sopenharmony_ci        self.checkParam(widget, 'padding', 5, expected=('5',))
337db96d56Sopenharmony_ci        self.checkParam(widget, 'padding', (5, 6), expected=('5', '6'))
347db96d56Sopenharmony_ci        self.checkParam(widget, 'padding', (5, 6, 7),
357db96d56Sopenharmony_ci                        expected=('5', '6', '7'))
367db96d56Sopenharmony_ci        self.checkParam(widget, 'padding', (5, 6, 7, 8),
377db96d56Sopenharmony_ci                        expected=('5', '6', '7', '8'))
387db96d56Sopenharmony_ci        self.checkParam(widget, 'padding', ('5p', '6p', '7p', '8p'))
397db96d56Sopenharmony_ci        self.checkParam(widget, 'padding', (), expected='')
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci    def test_configure_style(self):
427db96d56Sopenharmony_ci        widget = self.create()
437db96d56Sopenharmony_ci        self.assertEqual(widget['style'], '')
447db96d56Sopenharmony_ci        errmsg = 'Layout Foo not found'
457db96d56Sopenharmony_ci        if hasattr(self, 'default_orient'):
467db96d56Sopenharmony_ci            errmsg = ('Layout %s.Foo not found' %
477db96d56Sopenharmony_ci                      getattr(self, 'default_orient').title())
487db96d56Sopenharmony_ci        self.checkInvalidParam(widget, 'style', 'Foo',
497db96d56Sopenharmony_ci                errmsg=errmsg)
507db96d56Sopenharmony_ci        widget2 = self.create(class_='Foo')
517db96d56Sopenharmony_ci        self.assertEqual(widget2['class'], 'Foo')
527db96d56Sopenharmony_ci        # XXX
537db96d56Sopenharmony_ci        pass
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci
567db96d56Sopenharmony_ciclass WidgetTest(AbstractTkTest, unittest.TestCase):
577db96d56Sopenharmony_ci    """Tests methods available in every ttk widget."""
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ci    def setUp(self):
607db96d56Sopenharmony_ci        super().setUp()
617db96d56Sopenharmony_ci        self.widget = ttk.Button(self.root, width=0, text="Text")
627db96d56Sopenharmony_ci        self.widget.pack()
637db96d56Sopenharmony_ci
647db96d56Sopenharmony_ci    def test_identify(self):
657db96d56Sopenharmony_ci        self.widget.update()
667db96d56Sopenharmony_ci        self.assertEqual(self.widget.identify(
677db96d56Sopenharmony_ci            int(self.widget.winfo_width() / 2),
687db96d56Sopenharmony_ci            int(self.widget.winfo_height() / 2)
697db96d56Sopenharmony_ci            ), "label")
707db96d56Sopenharmony_ci        self.assertEqual(self.widget.identify(-1, -1), "")
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.widget.identify, None, 5)
737db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.widget.identify, 5, None)
747db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.widget.identify, 5, '')
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ci    def test_widget_state(self):
777db96d56Sopenharmony_ci        # XXX not sure about the portability of all these tests
787db96d56Sopenharmony_ci        self.assertEqual(self.widget.state(), ())
797db96d56Sopenharmony_ci        self.assertEqual(self.widget.instate(['!disabled']), True)
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci        # changing from !disabled to disabled
827db96d56Sopenharmony_ci        self.assertEqual(self.widget.state(['disabled']), ('!disabled', ))
837db96d56Sopenharmony_ci        # no state change
847db96d56Sopenharmony_ci        self.assertEqual(self.widget.state(['disabled']), ())
857db96d56Sopenharmony_ci        # change back to !disable but also active
867db96d56Sopenharmony_ci        self.assertEqual(self.widget.state(['!disabled', 'active']),
877db96d56Sopenharmony_ci            ('!active', 'disabled'))
887db96d56Sopenharmony_ci        # no state changes, again
897db96d56Sopenharmony_ci        self.assertEqual(self.widget.state(['!disabled', 'active']), ())
907db96d56Sopenharmony_ci        self.assertEqual(self.widget.state(['active', '!disabled']), ())
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci        def test_cb(arg1, **kw):
937db96d56Sopenharmony_ci            return arg1, kw
947db96d56Sopenharmony_ci        self.assertEqual(self.widget.instate(['!disabled'],
957db96d56Sopenharmony_ci            test_cb, "hi", **{"msg": "there"}),
967db96d56Sopenharmony_ci            ('hi', {'msg': 'there'}))
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ci        # attempt to set invalid statespec
997db96d56Sopenharmony_ci        currstate = self.widget.state()
1007db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.widget.instate,
1017db96d56Sopenharmony_ci            ['badstate'])
1027db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.widget.instate,
1037db96d56Sopenharmony_ci            ['disabled', 'badstate'])
1047db96d56Sopenharmony_ci        # verify that widget didn't change its state
1057db96d56Sopenharmony_ci        self.assertEqual(currstate, self.widget.state())
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci        # ensuring that passing None as state doesn't modify current state
1087db96d56Sopenharmony_ci        self.widget.state(['active', '!disabled'])
1097db96d56Sopenharmony_ci        self.assertEqual(self.widget.state(), ('active', ))
1107db96d56Sopenharmony_ci
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ciclass AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
1137db96d56Sopenharmony_ci    _conv_pixels = False
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
1177db96d56Sopenharmony_ciclass FrameTest(AbstractToplevelTest, unittest.TestCase):
1187db96d56Sopenharmony_ci    OPTIONS = (
1197db96d56Sopenharmony_ci        'borderwidth', 'class', 'cursor', 'height',
1207db96d56Sopenharmony_ci        'padding', 'relief', 'style', 'takefocus',
1217db96d56Sopenharmony_ci        'width',
1227db96d56Sopenharmony_ci    )
1237db96d56Sopenharmony_ci
1247db96d56Sopenharmony_ci    def create(self, **kwargs):
1257db96d56Sopenharmony_ci        return ttk.Frame(self.root, **kwargs)
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
1297db96d56Sopenharmony_ciclass LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
1307db96d56Sopenharmony_ci    OPTIONS = (
1317db96d56Sopenharmony_ci        'borderwidth', 'class', 'cursor', 'height',
1327db96d56Sopenharmony_ci        'labelanchor', 'labelwidget',
1337db96d56Sopenharmony_ci        'padding', 'relief', 'style', 'takefocus',
1347db96d56Sopenharmony_ci        'text', 'underline', 'width',
1357db96d56Sopenharmony_ci    )
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_ci    def create(self, **kwargs):
1387db96d56Sopenharmony_ci        return ttk.LabelFrame(self.root, **kwargs)
1397db96d56Sopenharmony_ci
1407db96d56Sopenharmony_ci    def test_configure_labelanchor(self):
1417db96d56Sopenharmony_ci        widget = self.create()
1427db96d56Sopenharmony_ci        self.checkEnumParam(widget, 'labelanchor',
1437db96d56Sopenharmony_ci                'e', 'en', 'es', 'n', 'ne', 'nw', 's', 'se', 'sw', 'w', 'wn', 'ws',
1447db96d56Sopenharmony_ci                errmsg='Bad label anchor specification {}')
1457db96d56Sopenharmony_ci        self.checkInvalidParam(widget, 'labelanchor', 'center')
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ci    def test_configure_labelwidget(self):
1487db96d56Sopenharmony_ci        widget = self.create()
1497db96d56Sopenharmony_ci        label = ttk.Label(self.root, text='Mupp', name='foo')
1507db96d56Sopenharmony_ci        self.checkParam(widget, 'labelwidget', label, expected='.foo')
1517db96d56Sopenharmony_ci        label.destroy()
1527db96d56Sopenharmony_ci
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_ciclass AbstractLabelTest(AbstractWidgetTest):
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_ci    def checkImageParam(self, widget, name):
1577db96d56Sopenharmony_ci        image = tkinter.PhotoImage(master=self.root, name='image1')
1587db96d56Sopenharmony_ci        image2 = tkinter.PhotoImage(master=self.root, name='image2')
1597db96d56Sopenharmony_ci        self.checkParam(widget, name, image, expected=('image1',))
1607db96d56Sopenharmony_ci        self.checkParam(widget, name, 'image1', expected=('image1',))
1617db96d56Sopenharmony_ci        self.checkParam(widget, name, (image,), expected=('image1',))
1627db96d56Sopenharmony_ci        self.checkParam(widget, name, (image, 'active', image2),
1637db96d56Sopenharmony_ci                        expected=('image1', 'active', 'image2'))
1647db96d56Sopenharmony_ci        self.checkParam(widget, name, 'image1 active image2',
1657db96d56Sopenharmony_ci                        expected=('image1', 'active', 'image2'))
1667db96d56Sopenharmony_ci        self.checkInvalidParam(widget, name, 'spam',
1677db96d56Sopenharmony_ci                errmsg='image "spam" doesn\'t exist')
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci    def test_configure_compound(self):
1707db96d56Sopenharmony_ci        options = 'none text image center top bottom left right'.split()
1717db96d56Sopenharmony_ci        errmsg = (
1727db96d56Sopenharmony_ci            'bad compound "{}": must be'
1737db96d56Sopenharmony_ci            f' {", ".join(options[:-1])}, or {options[-1]}'
1747db96d56Sopenharmony_ci            )
1757db96d56Sopenharmony_ci        widget = self.create()
1767db96d56Sopenharmony_ci        self.checkEnumParam(widget, 'compound', *options, errmsg=errmsg)
1777db96d56Sopenharmony_ci
1787db96d56Sopenharmony_ci    def test_configure_state(self):
1797db96d56Sopenharmony_ci        widget = self.create()
1807db96d56Sopenharmony_ci        self.checkParams(widget, 'state', 'active', 'disabled', 'normal')
1817db96d56Sopenharmony_ci
1827db96d56Sopenharmony_ci    def test_configure_width(self):
1837db96d56Sopenharmony_ci        widget = self.create()
1847db96d56Sopenharmony_ci        self.checkParams(widget, 'width', 402, -402, 0)
1857db96d56Sopenharmony_ci
1867db96d56Sopenharmony_ci
1877db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
1887db96d56Sopenharmony_ciclass LabelTest(AbstractLabelTest, unittest.TestCase):
1897db96d56Sopenharmony_ci    OPTIONS = (
1907db96d56Sopenharmony_ci        'anchor', 'background', 'borderwidth',
1917db96d56Sopenharmony_ci        'class', 'compound', 'cursor', 'font', 'foreground',
1927db96d56Sopenharmony_ci        'image', 'justify', 'padding', 'relief', 'state', 'style',
1937db96d56Sopenharmony_ci        'takefocus', 'text', 'textvariable',
1947db96d56Sopenharmony_ci        'underline', 'width', 'wraplength',
1957db96d56Sopenharmony_ci    )
1967db96d56Sopenharmony_ci    _conv_pixels = False
1977db96d56Sopenharmony_ci
1987db96d56Sopenharmony_ci    def create(self, **kwargs):
1997db96d56Sopenharmony_ci        return ttk.Label(self.root, **kwargs)
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci    def test_configure_font(self):
2027db96d56Sopenharmony_ci        widget = self.create()
2037db96d56Sopenharmony_ci        self.checkParam(widget, 'font',
2047db96d56Sopenharmony_ci                        '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
2057db96d56Sopenharmony_ci
2067db96d56Sopenharmony_ci
2077db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
2087db96d56Sopenharmony_ciclass ButtonTest(AbstractLabelTest, unittest.TestCase):
2097db96d56Sopenharmony_ci    OPTIONS = (
2107db96d56Sopenharmony_ci        'class', 'command', 'compound', 'cursor', 'default',
2117db96d56Sopenharmony_ci        'image', 'padding', 'state', 'style',
2127db96d56Sopenharmony_ci        'takefocus', 'text', 'textvariable',
2137db96d56Sopenharmony_ci        'underline', 'width',
2147db96d56Sopenharmony_ci    )
2157db96d56Sopenharmony_ci
2167db96d56Sopenharmony_ci    def create(self, **kwargs):
2177db96d56Sopenharmony_ci        return ttk.Button(self.root, **kwargs)
2187db96d56Sopenharmony_ci
2197db96d56Sopenharmony_ci    def test_configure_default(self):
2207db96d56Sopenharmony_ci        widget = self.create()
2217db96d56Sopenharmony_ci        self.checkEnumParam(widget, 'default', 'normal', 'active', 'disabled')
2227db96d56Sopenharmony_ci
2237db96d56Sopenharmony_ci    def test_invoke(self):
2247db96d56Sopenharmony_ci        success = []
2257db96d56Sopenharmony_ci        btn = ttk.Button(self.root, command=lambda: success.append(1))
2267db96d56Sopenharmony_ci        btn.invoke()
2277db96d56Sopenharmony_ci        self.assertTrue(success)
2287db96d56Sopenharmony_ci
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
2317db96d56Sopenharmony_ciclass CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
2327db96d56Sopenharmony_ci    OPTIONS = (
2337db96d56Sopenharmony_ci        'class', 'command', 'compound', 'cursor',
2347db96d56Sopenharmony_ci        'image',
2357db96d56Sopenharmony_ci        'offvalue', 'onvalue',
2367db96d56Sopenharmony_ci        'padding', 'state', 'style',
2377db96d56Sopenharmony_ci        'takefocus', 'text', 'textvariable',
2387db96d56Sopenharmony_ci        'underline', 'variable', 'width',
2397db96d56Sopenharmony_ci    )
2407db96d56Sopenharmony_ci
2417db96d56Sopenharmony_ci    def create(self, **kwargs):
2427db96d56Sopenharmony_ci        return ttk.Checkbutton(self.root, **kwargs)
2437db96d56Sopenharmony_ci
2447db96d56Sopenharmony_ci    def test_configure_offvalue(self):
2457db96d56Sopenharmony_ci        widget = self.create()
2467db96d56Sopenharmony_ci        self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
2477db96d56Sopenharmony_ci
2487db96d56Sopenharmony_ci    def test_configure_onvalue(self):
2497db96d56Sopenharmony_ci        widget = self.create()
2507db96d56Sopenharmony_ci        self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
2517db96d56Sopenharmony_ci
2527db96d56Sopenharmony_ci    def test_invoke(self):
2537db96d56Sopenharmony_ci        success = []
2547db96d56Sopenharmony_ci        def cb_test():
2557db96d56Sopenharmony_ci            success.append(1)
2567db96d56Sopenharmony_ci            return "cb test called"
2577db96d56Sopenharmony_ci
2587db96d56Sopenharmony_ci        cbtn = ttk.Checkbutton(self.root, command=cb_test)
2597db96d56Sopenharmony_ci        # the variable automatically created by ttk.Checkbutton is actually
2607db96d56Sopenharmony_ci        # undefined till we invoke the Checkbutton
2617db96d56Sopenharmony_ci        self.assertEqual(cbtn.state(), ('alternate', ))
2627db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, cbtn.tk.globalgetvar,
2637db96d56Sopenharmony_ci            cbtn['variable'])
2647db96d56Sopenharmony_ci
2657db96d56Sopenharmony_ci        res = cbtn.invoke()
2667db96d56Sopenharmony_ci        self.assertEqual(res, "cb test called")
2677db96d56Sopenharmony_ci        self.assertEqual(cbtn['onvalue'],
2687db96d56Sopenharmony_ci            cbtn.tk.globalgetvar(cbtn['variable']))
2697db96d56Sopenharmony_ci        self.assertTrue(success)
2707db96d56Sopenharmony_ci
2717db96d56Sopenharmony_ci        cbtn['command'] = ''
2727db96d56Sopenharmony_ci        res = cbtn.invoke()
2737db96d56Sopenharmony_ci        self.assertFalse(str(res))
2747db96d56Sopenharmony_ci        self.assertLessEqual(len(success), 1)
2757db96d56Sopenharmony_ci        self.assertEqual(cbtn['offvalue'],
2767db96d56Sopenharmony_ci            cbtn.tk.globalgetvar(cbtn['variable']))
2777db96d56Sopenharmony_ci
2787db96d56Sopenharmony_ci    def test_unique_variables(self):
2797db96d56Sopenharmony_ci        frames = []
2807db96d56Sopenharmony_ci        buttons = []
2817db96d56Sopenharmony_ci        for i in range(2):
2827db96d56Sopenharmony_ci            f = ttk.Frame(self.root)
2837db96d56Sopenharmony_ci            f.pack()
2847db96d56Sopenharmony_ci            frames.append(f)
2857db96d56Sopenharmony_ci            for j in 'AB':
2867db96d56Sopenharmony_ci                b = ttk.Checkbutton(f, text=j)
2877db96d56Sopenharmony_ci                b.pack()
2887db96d56Sopenharmony_ci                buttons.append(b)
2897db96d56Sopenharmony_ci        variables = [str(b['variable']) for b in buttons]
2907db96d56Sopenharmony_ci        print(variables)
2917db96d56Sopenharmony_ci        self.assertEqual(len(set(variables)), 4, variables)
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_ci
2947db96d56Sopenharmony_ci@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
2957db96d56Sopenharmony_ciclass EntryTest(AbstractWidgetTest, unittest.TestCase):
2967db96d56Sopenharmony_ci    OPTIONS = (
2977db96d56Sopenharmony_ci        'background', 'class', 'cursor',
2987db96d56Sopenharmony_ci        'exportselection', 'font', 'foreground',
2997db96d56Sopenharmony_ci        'invalidcommand', 'justify',
3007db96d56Sopenharmony_ci        'show', 'state', 'style', 'takefocus', 'textvariable',
3017db96d56Sopenharmony_ci        'validate', 'validatecommand', 'width', 'xscrollcommand',
3027db96d56Sopenharmony_ci    )
3037db96d56Sopenharmony_ci    IDENTIFY_AS = 'Entry.field' if sys.platform == 'darwin' else 'textarea'
3047db96d56Sopenharmony_ci
3057db96d56Sopenharmony_ci    def setUp(self):
3067db96d56Sopenharmony_ci        super().setUp()
3077db96d56Sopenharmony_ci        self.entry = self.create()
3087db96d56Sopenharmony_ci
3097db96d56Sopenharmony_ci    def create(self, **kwargs):
3107db96d56Sopenharmony_ci        return ttk.Entry(self.root, **kwargs)
3117db96d56Sopenharmony_ci
3127db96d56Sopenharmony_ci    def test_configure_invalidcommand(self):
3137db96d56Sopenharmony_ci        widget = self.create()
3147db96d56Sopenharmony_ci        self.checkCommandParam(widget, 'invalidcommand')
3157db96d56Sopenharmony_ci
3167db96d56Sopenharmony_ci    def test_configure_show(self):
3177db96d56Sopenharmony_ci        widget = self.create()
3187db96d56Sopenharmony_ci        self.checkParam(widget, 'show', '*')
3197db96d56Sopenharmony_ci        self.checkParam(widget, 'show', '')
3207db96d56Sopenharmony_ci        self.checkParam(widget, 'show', ' ')
3217db96d56Sopenharmony_ci
3227db96d56Sopenharmony_ci    def test_configure_state(self):
3237db96d56Sopenharmony_ci        widget = self.create()
3247db96d56Sopenharmony_ci        self.checkParams(widget, 'state',
3257db96d56Sopenharmony_ci                         'disabled', 'normal', 'readonly')
3267db96d56Sopenharmony_ci
3277db96d56Sopenharmony_ci    def test_configure_validate(self):
3287db96d56Sopenharmony_ci        widget = self.create()
3297db96d56Sopenharmony_ci        self.checkEnumParam(widget, 'validate',
3307db96d56Sopenharmony_ci                'all', 'key', 'focus', 'focusin', 'focusout', 'none')
3317db96d56Sopenharmony_ci
3327db96d56Sopenharmony_ci    def test_configure_validatecommand(self):
3337db96d56Sopenharmony_ci        widget = self.create()
3347db96d56Sopenharmony_ci        self.checkCommandParam(widget, 'validatecommand')
3357db96d56Sopenharmony_ci
3367db96d56Sopenharmony_ci    def test_bbox(self):
3377db96d56Sopenharmony_ci        self.assertIsBoundingBox(self.entry.bbox(0))
3387db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.entry.bbox, 'noindex')
3397db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.entry.bbox, None)
3407db96d56Sopenharmony_ci
3417db96d56Sopenharmony_ci    def test_identify(self):
3427db96d56Sopenharmony_ci        self.entry.pack()
3437db96d56Sopenharmony_ci        self.entry.update()
3447db96d56Sopenharmony_ci
3457db96d56Sopenharmony_ci        # bpo-27313: macOS Cocoa widget differs from X, allow either
3467db96d56Sopenharmony_ci        self.assertEqual(self.entry.identify(5, 5), self.IDENTIFY_AS)
3477db96d56Sopenharmony_ci        self.assertEqual(self.entry.identify(-1, -1), "")
3487db96d56Sopenharmony_ci
3497db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.entry.identify, None, 5)
3507db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.entry.identify, 5, None)
3517db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.entry.identify, 5, '')
3527db96d56Sopenharmony_ci
3537db96d56Sopenharmony_ci    def test_validation_options(self):
3547db96d56Sopenharmony_ci        success = []
3557db96d56Sopenharmony_ci        test_invalid = lambda: success.append(True)
3567db96d56Sopenharmony_ci
3577db96d56Sopenharmony_ci        self.entry['validate'] = 'none'
3587db96d56Sopenharmony_ci        self.entry['validatecommand'] = lambda: False
3597db96d56Sopenharmony_ci
3607db96d56Sopenharmony_ci        self.entry['invalidcommand'] = test_invalid
3617db96d56Sopenharmony_ci        self.entry.validate()
3627db96d56Sopenharmony_ci        self.assertTrue(success)
3637db96d56Sopenharmony_ci
3647db96d56Sopenharmony_ci        self.entry['invalidcommand'] = ''
3657db96d56Sopenharmony_ci        self.entry.validate()
3667db96d56Sopenharmony_ci        self.assertEqual(len(success), 1)
3677db96d56Sopenharmony_ci
3687db96d56Sopenharmony_ci        self.entry['invalidcommand'] = test_invalid
3697db96d56Sopenharmony_ci        self.entry['validatecommand'] = lambda: True
3707db96d56Sopenharmony_ci        self.entry.validate()
3717db96d56Sopenharmony_ci        self.assertEqual(len(success), 1)
3727db96d56Sopenharmony_ci
3737db96d56Sopenharmony_ci        self.entry['validatecommand'] = ''
3747db96d56Sopenharmony_ci        self.entry.validate()
3757db96d56Sopenharmony_ci        self.assertEqual(len(success), 1)
3767db96d56Sopenharmony_ci
3777db96d56Sopenharmony_ci        self.entry['validatecommand'] = True
3787db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.entry.validate)
3797db96d56Sopenharmony_ci
3807db96d56Sopenharmony_ci    def test_validation(self):
3817db96d56Sopenharmony_ci        validation = []
3827db96d56Sopenharmony_ci        def validate(to_insert):
3837db96d56Sopenharmony_ci            if not 'a' <= to_insert.lower() <= 'z':
3847db96d56Sopenharmony_ci                validation.append(False)
3857db96d56Sopenharmony_ci                return False
3867db96d56Sopenharmony_ci            validation.append(True)
3877db96d56Sopenharmony_ci            return True
3887db96d56Sopenharmony_ci
3897db96d56Sopenharmony_ci        self.entry['validate'] = 'key'
3907db96d56Sopenharmony_ci        self.entry['validatecommand'] = self.entry.register(validate), '%S'
3917db96d56Sopenharmony_ci
3927db96d56Sopenharmony_ci        self.entry.insert('end', 1)
3937db96d56Sopenharmony_ci        self.entry.insert('end', 'a')
3947db96d56Sopenharmony_ci        self.assertEqual(validation, [False, True])
3957db96d56Sopenharmony_ci        self.assertEqual(self.entry.get(), 'a')
3967db96d56Sopenharmony_ci
3977db96d56Sopenharmony_ci    def test_revalidation(self):
3987db96d56Sopenharmony_ci        def validate(content):
3997db96d56Sopenharmony_ci            for letter in content:
4007db96d56Sopenharmony_ci                if not 'a' <= letter.lower() <= 'z':
4017db96d56Sopenharmony_ci                    return False
4027db96d56Sopenharmony_ci            return True
4037db96d56Sopenharmony_ci
4047db96d56Sopenharmony_ci        self.entry['validatecommand'] = self.entry.register(validate), '%P'
4057db96d56Sopenharmony_ci
4067db96d56Sopenharmony_ci        self.entry.insert('end', 'avocado')
4077db96d56Sopenharmony_ci        self.assertEqual(self.entry.validate(), True)
4087db96d56Sopenharmony_ci        self.assertEqual(self.entry.state(), ())
4097db96d56Sopenharmony_ci
4107db96d56Sopenharmony_ci        self.entry.delete(0, 'end')
4117db96d56Sopenharmony_ci        self.assertEqual(self.entry.get(), '')
4127db96d56Sopenharmony_ci
4137db96d56Sopenharmony_ci        self.entry.insert('end', 'a1b')
4147db96d56Sopenharmony_ci        self.assertEqual(self.entry.validate(), False)
4157db96d56Sopenharmony_ci        self.assertEqual(self.entry.state(), ('invalid', ))
4167db96d56Sopenharmony_ci
4177db96d56Sopenharmony_ci        self.entry.delete(1)
4187db96d56Sopenharmony_ci        self.assertEqual(self.entry.validate(), True)
4197db96d56Sopenharmony_ci        self.assertEqual(self.entry.state(), ())
4207db96d56Sopenharmony_ci
4217db96d56Sopenharmony_ci
4227db96d56Sopenharmony_ci@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
4237db96d56Sopenharmony_ciclass ComboboxTest(EntryTest, unittest.TestCase):
4247db96d56Sopenharmony_ci    OPTIONS = (
4257db96d56Sopenharmony_ci        'background', 'class', 'cursor', 'exportselection',
4267db96d56Sopenharmony_ci        'font', 'foreground', 'height', 'invalidcommand',
4277db96d56Sopenharmony_ci        'justify', 'postcommand', 'show', 'state', 'style',
4287db96d56Sopenharmony_ci        'takefocus', 'textvariable',
4297db96d56Sopenharmony_ci        'validate', 'validatecommand', 'values',
4307db96d56Sopenharmony_ci        'width', 'xscrollcommand',
4317db96d56Sopenharmony_ci    )
4327db96d56Sopenharmony_ci    IDENTIFY_AS = 'Combobox.button' if sys.platform == 'darwin' else 'textarea'
4337db96d56Sopenharmony_ci
4347db96d56Sopenharmony_ci    def setUp(self):
4357db96d56Sopenharmony_ci        super().setUp()
4367db96d56Sopenharmony_ci        self.combo = self.create()
4377db96d56Sopenharmony_ci
4387db96d56Sopenharmony_ci    def create(self, **kwargs):
4397db96d56Sopenharmony_ci        return ttk.Combobox(self.root, **kwargs)
4407db96d56Sopenharmony_ci
4417db96d56Sopenharmony_ci    def test_configure_height(self):
4427db96d56Sopenharmony_ci        widget = self.create()
4437db96d56Sopenharmony_ci        self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i')
4447db96d56Sopenharmony_ci
4457db96d56Sopenharmony_ci    def _show_drop_down_listbox(self):
4467db96d56Sopenharmony_ci        width = self.combo.winfo_width()
4477db96d56Sopenharmony_ci        x, y = width - 5, 5
4487db96d56Sopenharmony_ci        if sys.platform != 'darwin':  # there's no down arrow on macOS
4497db96d56Sopenharmony_ci            self.assertRegex(self.combo.identify(x, y), r'.*downarrow\Z')
4507db96d56Sopenharmony_ci        self.combo.event_generate('<ButtonPress-1>', x=x, y=y)
4517db96d56Sopenharmony_ci        self.combo.event_generate('<ButtonRelease-1>', x=x, y=y)
4527db96d56Sopenharmony_ci        self.combo.update_idletasks()
4537db96d56Sopenharmony_ci
4547db96d56Sopenharmony_ci    def test_virtual_event(self):
4557db96d56Sopenharmony_ci        success = []
4567db96d56Sopenharmony_ci
4577db96d56Sopenharmony_ci        self.combo['values'] = [1]
4587db96d56Sopenharmony_ci        self.combo.bind('<<ComboboxSelected>>',
4597db96d56Sopenharmony_ci            lambda evt: success.append(True))
4607db96d56Sopenharmony_ci        self.combo.pack()
4617db96d56Sopenharmony_ci        self.combo.update()
4627db96d56Sopenharmony_ci
4637db96d56Sopenharmony_ci        height = self.combo.winfo_height()
4647db96d56Sopenharmony_ci        self._show_drop_down_listbox()
4657db96d56Sopenharmony_ci        self.combo.update()
4667db96d56Sopenharmony_ci        self.combo.event_generate('<Return>')
4677db96d56Sopenharmony_ci        self.combo.update()
4687db96d56Sopenharmony_ci
4697db96d56Sopenharmony_ci        self.assertTrue(success)
4707db96d56Sopenharmony_ci
4717db96d56Sopenharmony_ci    def test_configure_postcommand(self):
4727db96d56Sopenharmony_ci        success = []
4737db96d56Sopenharmony_ci
4747db96d56Sopenharmony_ci        self.combo['postcommand'] = lambda: success.append(True)
4757db96d56Sopenharmony_ci        self.combo.pack()
4767db96d56Sopenharmony_ci        self.combo.update()
4777db96d56Sopenharmony_ci
4787db96d56Sopenharmony_ci        self._show_drop_down_listbox()
4797db96d56Sopenharmony_ci        self.assertTrue(success)
4807db96d56Sopenharmony_ci
4817db96d56Sopenharmony_ci        # testing postcommand removal
4827db96d56Sopenharmony_ci        self.combo['postcommand'] = ''
4837db96d56Sopenharmony_ci        self._show_drop_down_listbox()
4847db96d56Sopenharmony_ci        self.assertEqual(len(success), 1)
4857db96d56Sopenharmony_ci
4867db96d56Sopenharmony_ci    def test_configure_values(self):
4877db96d56Sopenharmony_ci        def check_get_current(getval, currval):
4887db96d56Sopenharmony_ci            self.assertEqual(self.combo.get(), getval)
4897db96d56Sopenharmony_ci            self.assertEqual(self.combo.current(), currval)
4907db96d56Sopenharmony_ci
4917db96d56Sopenharmony_ci        self.assertEqual(self.combo['values'], '')
4927db96d56Sopenharmony_ci        check_get_current('', -1)
4937db96d56Sopenharmony_ci
4947db96d56Sopenharmony_ci        self.checkParam(self.combo, 'values', 'mon tue wed thur',
4957db96d56Sopenharmony_ci                        expected=('mon', 'tue', 'wed', 'thur'))
4967db96d56Sopenharmony_ci        self.checkParam(self.combo, 'values', ('mon', 'tue', 'wed', 'thur'))
4977db96d56Sopenharmony_ci        self.checkParam(self.combo, 'values', (42, 3.14, '', 'any string'))
4987db96d56Sopenharmony_ci        self.checkParam(self.combo, 'values', '')
4997db96d56Sopenharmony_ci
5007db96d56Sopenharmony_ci        self.combo['values'] = ['a', 1, 'c']
5017db96d56Sopenharmony_ci
5027db96d56Sopenharmony_ci        self.combo.set('c')
5037db96d56Sopenharmony_ci        check_get_current('c', 2)
5047db96d56Sopenharmony_ci
5057db96d56Sopenharmony_ci        self.combo.current(0)
5067db96d56Sopenharmony_ci        check_get_current('a', 0)
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_ci        self.combo.set('d')
5097db96d56Sopenharmony_ci        check_get_current('d', -1)
5107db96d56Sopenharmony_ci
5117db96d56Sopenharmony_ci        # testing values with empty string
5127db96d56Sopenharmony_ci        self.combo.set('')
5137db96d56Sopenharmony_ci        self.combo['values'] = (1, 2, '', 3)
5147db96d56Sopenharmony_ci        check_get_current('', 2)
5157db96d56Sopenharmony_ci
5167db96d56Sopenharmony_ci        # testing values with empty string set through configure
5177db96d56Sopenharmony_ci        self.combo.configure(values=[1, '', 2])
5187db96d56Sopenharmony_ci        self.assertEqual(self.combo['values'],
5197db96d56Sopenharmony_ci                         ('1', '', '2') if self.wantobjects else
5207db96d56Sopenharmony_ci                         '1 {} 2')
5217db96d56Sopenharmony_ci
5227db96d56Sopenharmony_ci        # testing values with spaces
5237db96d56Sopenharmony_ci        self.combo['values'] = ['a b', 'a\tb', 'a\nb']
5247db96d56Sopenharmony_ci        self.assertEqual(self.combo['values'],
5257db96d56Sopenharmony_ci                         ('a b', 'a\tb', 'a\nb') if self.wantobjects else
5267db96d56Sopenharmony_ci                         '{a b} {a\tb} {a\nb}')
5277db96d56Sopenharmony_ci
5287db96d56Sopenharmony_ci        # testing values with special characters
5297db96d56Sopenharmony_ci        self.combo['values'] = [r'a\tb', '"a"', '} {']
5307db96d56Sopenharmony_ci        self.assertEqual(self.combo['values'],
5317db96d56Sopenharmony_ci                         (r'a\tb', '"a"', '} {') if self.wantobjects else
5327db96d56Sopenharmony_ci                         r'a\\tb {"a"} \}\ \{')
5337db96d56Sopenharmony_ci
5347db96d56Sopenharmony_ci        # out of range
5357db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.combo.current,
5367db96d56Sopenharmony_ci            len(self.combo['values']))
5377db96d56Sopenharmony_ci        # it expects an integer (or something that can be converted to int)
5387db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.combo.current, '')
5397db96d56Sopenharmony_ci
5407db96d56Sopenharmony_ci        # testing creating combobox with empty string in values
5417db96d56Sopenharmony_ci        combo2 = ttk.Combobox(self.root, values=[1, 2, ''])
5427db96d56Sopenharmony_ci        self.assertEqual(combo2['values'],
5437db96d56Sopenharmony_ci                         ('1', '2', '') if self.wantobjects else '1 2 {}')
5447db96d56Sopenharmony_ci        combo2.destroy()
5457db96d56Sopenharmony_ci
5467db96d56Sopenharmony_ci
5477db96d56Sopenharmony_ci@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
5487db96d56Sopenharmony_ciclass PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
5497db96d56Sopenharmony_ci    OPTIONS = (
5507db96d56Sopenharmony_ci        'class', 'cursor', 'height',
5517db96d56Sopenharmony_ci        'orient', 'style', 'takefocus', 'width',
5527db96d56Sopenharmony_ci    )
5537db96d56Sopenharmony_ci
5547db96d56Sopenharmony_ci    def setUp(self):
5557db96d56Sopenharmony_ci        super().setUp()
5567db96d56Sopenharmony_ci        self.paned = self.create()
5577db96d56Sopenharmony_ci
5587db96d56Sopenharmony_ci    def create(self, **kwargs):
5597db96d56Sopenharmony_ci        return ttk.PanedWindow(self.root, **kwargs)
5607db96d56Sopenharmony_ci
5617db96d56Sopenharmony_ci    def test_configure_orient(self):
5627db96d56Sopenharmony_ci        widget = self.create()
5637db96d56Sopenharmony_ci        self.assertEqual(str(widget['orient']), 'vertical')
5647db96d56Sopenharmony_ci        errmsg='attempt to change read-only option'
5657db96d56Sopenharmony_ci        if get_tk_patchlevel() < (8, 6, 0, 'beta', 3):
5667db96d56Sopenharmony_ci            errmsg='Attempt to change read-only option'
5677db96d56Sopenharmony_ci        self.checkInvalidParam(widget, 'orient', 'horizontal',
5687db96d56Sopenharmony_ci                errmsg=errmsg)
5697db96d56Sopenharmony_ci        widget2 = self.create(orient='horizontal')
5707db96d56Sopenharmony_ci        self.assertEqual(str(widget2['orient']), 'horizontal')
5717db96d56Sopenharmony_ci
5727db96d56Sopenharmony_ci    def test_add(self):
5737db96d56Sopenharmony_ci        # attempt to add a child that is not a direct child of the paned window
5747db96d56Sopenharmony_ci        label = ttk.Label(self.paned)
5757db96d56Sopenharmony_ci        child = ttk.Label(label)
5767db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.add, child)
5777db96d56Sopenharmony_ci        label.destroy()
5787db96d56Sopenharmony_ci        child.destroy()
5797db96d56Sopenharmony_ci        # another attempt
5807db96d56Sopenharmony_ci        label = ttk.Label(self.root)
5817db96d56Sopenharmony_ci        child = ttk.Label(label)
5827db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.add, child)
5837db96d56Sopenharmony_ci        child.destroy()
5847db96d56Sopenharmony_ci        label.destroy()
5857db96d56Sopenharmony_ci
5867db96d56Sopenharmony_ci        good_child = ttk.Label(self.root)
5877db96d56Sopenharmony_ci        self.paned.add(good_child)
5887db96d56Sopenharmony_ci        # re-adding a child is not accepted
5897db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.add, good_child)
5907db96d56Sopenharmony_ci
5917db96d56Sopenharmony_ci        other_child = ttk.Label(self.paned)
5927db96d56Sopenharmony_ci        self.paned.add(other_child)
5937db96d56Sopenharmony_ci        self.assertEqual(self.paned.pane(0), self.paned.pane(1))
5947db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.pane, 2)
5957db96d56Sopenharmony_ci        good_child.destroy()
5967db96d56Sopenharmony_ci        other_child.destroy()
5977db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.pane, 0)
5987db96d56Sopenharmony_ci
5997db96d56Sopenharmony_ci    def test_forget(self):
6007db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.forget, None)
6017db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.forget, 0)
6027db96d56Sopenharmony_ci
6037db96d56Sopenharmony_ci        self.paned.add(ttk.Label(self.root))
6047db96d56Sopenharmony_ci        self.paned.forget(0)
6057db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.forget, 0)
6067db96d56Sopenharmony_ci
6077db96d56Sopenharmony_ci    def test_insert(self):
6087db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.insert, None, 0)
6097db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.insert, 0, None)
6107db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.insert, 0, 0)
6117db96d56Sopenharmony_ci
6127db96d56Sopenharmony_ci        child = ttk.Label(self.root)
6137db96d56Sopenharmony_ci        child2 = ttk.Label(self.root)
6147db96d56Sopenharmony_ci        child3 = ttk.Label(self.root)
6157db96d56Sopenharmony_ci
6167db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.insert, 0, child)
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_ci        self.paned.insert('end', child2)
6197db96d56Sopenharmony_ci        self.paned.insert(0, child)
6207db96d56Sopenharmony_ci        self.assertEqual(self.paned.panes(), (str(child), str(child2)))
6217db96d56Sopenharmony_ci
6227db96d56Sopenharmony_ci        self.paned.insert(0, child2)
6237db96d56Sopenharmony_ci        self.assertEqual(self.paned.panes(), (str(child2), str(child)))
6247db96d56Sopenharmony_ci
6257db96d56Sopenharmony_ci        self.paned.insert('end', child3)
6267db96d56Sopenharmony_ci        self.assertEqual(self.paned.panes(),
6277db96d56Sopenharmony_ci            (str(child2), str(child), str(child3)))
6287db96d56Sopenharmony_ci
6297db96d56Sopenharmony_ci        # reinserting a child should move it to its current position
6307db96d56Sopenharmony_ci        panes = self.paned.panes()
6317db96d56Sopenharmony_ci        self.paned.insert('end', child3)
6327db96d56Sopenharmony_ci        self.assertEqual(panes, self.paned.panes())
6337db96d56Sopenharmony_ci
6347db96d56Sopenharmony_ci        # moving child3 to child2 position should result in child2 ending up
6357db96d56Sopenharmony_ci        # in previous child position and child ending up in previous child3
6367db96d56Sopenharmony_ci        # position
6377db96d56Sopenharmony_ci        self.paned.insert(child2, child3)
6387db96d56Sopenharmony_ci        self.assertEqual(self.paned.panes(),
6397db96d56Sopenharmony_ci            (str(child3), str(child2), str(child)))
6407db96d56Sopenharmony_ci
6417db96d56Sopenharmony_ci    def test_pane(self):
6427db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.pane, 0)
6437db96d56Sopenharmony_ci
6447db96d56Sopenharmony_ci        child = ttk.Label(self.root)
6457db96d56Sopenharmony_ci        self.paned.add(child)
6467db96d56Sopenharmony_ci        self.assertIsInstance(self.paned.pane(0), dict)
6477db96d56Sopenharmony_ci        self.assertEqual(self.paned.pane(0, weight=None),
6487db96d56Sopenharmony_ci                         0 if self.wantobjects else '0')
6497db96d56Sopenharmony_ci        # newer form for querying a single option
6507db96d56Sopenharmony_ci        self.assertEqual(self.paned.pane(0, 'weight'),
6517db96d56Sopenharmony_ci                         0 if self.wantobjects else '0')
6527db96d56Sopenharmony_ci        self.assertEqual(self.paned.pane(0), self.paned.pane(str(child)))
6537db96d56Sopenharmony_ci
6547db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.pane, 0,
6557db96d56Sopenharmony_ci            badoption='somevalue')
6567db96d56Sopenharmony_ci
6577db96d56Sopenharmony_ci    def test_sashpos(self):
6587db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.sashpos, None)
6597db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.sashpos, '')
6607db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.sashpos, 0)
6617db96d56Sopenharmony_ci
6627db96d56Sopenharmony_ci        child = ttk.Label(self.paned, text='a')
6637db96d56Sopenharmony_ci        self.paned.add(child, weight=1)
6647db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.sashpos, 0)
6657db96d56Sopenharmony_ci        child2 = ttk.Label(self.paned, text='b')
6667db96d56Sopenharmony_ci        self.paned.add(child2)
6677db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.paned.sashpos, 1)
6687db96d56Sopenharmony_ci
6697db96d56Sopenharmony_ci        self.paned.pack(expand=True, fill='both')
6707db96d56Sopenharmony_ci
6717db96d56Sopenharmony_ci        curr_pos = self.paned.sashpos(0)
6727db96d56Sopenharmony_ci        self.paned.sashpos(0, 1000)
6737db96d56Sopenharmony_ci        self.assertNotEqual(curr_pos, self.paned.sashpos(0))
6747db96d56Sopenharmony_ci        self.assertIsInstance(self.paned.sashpos(0), int)
6757db96d56Sopenharmony_ci
6767db96d56Sopenharmony_ci
6777db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
6787db96d56Sopenharmony_ciclass RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
6797db96d56Sopenharmony_ci    OPTIONS = (
6807db96d56Sopenharmony_ci        'class', 'command', 'compound', 'cursor',
6817db96d56Sopenharmony_ci        'image',
6827db96d56Sopenharmony_ci        'padding', 'state', 'style',
6837db96d56Sopenharmony_ci        'takefocus', 'text', 'textvariable',
6847db96d56Sopenharmony_ci        'underline', 'value', 'variable', 'width',
6857db96d56Sopenharmony_ci    )
6867db96d56Sopenharmony_ci
6877db96d56Sopenharmony_ci    def create(self, **kwargs):
6887db96d56Sopenharmony_ci        return ttk.Radiobutton(self.root, **kwargs)
6897db96d56Sopenharmony_ci
6907db96d56Sopenharmony_ci    def test_configure_value(self):
6917db96d56Sopenharmony_ci        widget = self.create()
6927db96d56Sopenharmony_ci        self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
6937db96d56Sopenharmony_ci
6947db96d56Sopenharmony_ci    def test_configure_invoke(self):
6957db96d56Sopenharmony_ci        success = []
6967db96d56Sopenharmony_ci        def cb_test():
6977db96d56Sopenharmony_ci            success.append(1)
6987db96d56Sopenharmony_ci            return "cb test called"
6997db96d56Sopenharmony_ci
7007db96d56Sopenharmony_ci        myvar = tkinter.IntVar(self.root)
7017db96d56Sopenharmony_ci        cbtn = ttk.Radiobutton(self.root, command=cb_test,
7027db96d56Sopenharmony_ci                               variable=myvar, value=0)
7037db96d56Sopenharmony_ci        cbtn2 = ttk.Radiobutton(self.root, command=cb_test,
7047db96d56Sopenharmony_ci                                variable=myvar, value=1)
7057db96d56Sopenharmony_ci
7067db96d56Sopenharmony_ci        if self.wantobjects:
7077db96d56Sopenharmony_ci            conv = lambda x: x
7087db96d56Sopenharmony_ci        else:
7097db96d56Sopenharmony_ci            conv = int
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ci        res = cbtn.invoke()
7127db96d56Sopenharmony_ci        self.assertEqual(res, "cb test called")
7137db96d56Sopenharmony_ci        self.assertEqual(conv(cbtn['value']), myvar.get())
7147db96d56Sopenharmony_ci        self.assertEqual(myvar.get(),
7157db96d56Sopenharmony_ci            conv(cbtn.tk.globalgetvar(cbtn['variable'])))
7167db96d56Sopenharmony_ci        self.assertTrue(success)
7177db96d56Sopenharmony_ci
7187db96d56Sopenharmony_ci        cbtn2['command'] = ''
7197db96d56Sopenharmony_ci        res = cbtn2.invoke()
7207db96d56Sopenharmony_ci        self.assertEqual(str(res), '')
7217db96d56Sopenharmony_ci        self.assertLessEqual(len(success), 1)
7227db96d56Sopenharmony_ci        self.assertEqual(conv(cbtn2['value']), myvar.get())
7237db96d56Sopenharmony_ci        self.assertEqual(myvar.get(),
7247db96d56Sopenharmony_ci            conv(cbtn.tk.globalgetvar(cbtn['variable'])))
7257db96d56Sopenharmony_ci
7267db96d56Sopenharmony_ci        self.assertEqual(str(cbtn['variable']), str(cbtn2['variable']))
7277db96d56Sopenharmony_ci
7287db96d56Sopenharmony_ci
7297db96d56Sopenharmony_ciclass MenubuttonTest(AbstractLabelTest, unittest.TestCase):
7307db96d56Sopenharmony_ci    OPTIONS = (
7317db96d56Sopenharmony_ci        'class', 'compound', 'cursor', 'direction',
7327db96d56Sopenharmony_ci        'image', 'menu', 'padding', 'state', 'style',
7337db96d56Sopenharmony_ci        'takefocus', 'text', 'textvariable',
7347db96d56Sopenharmony_ci        'underline', 'width',
7357db96d56Sopenharmony_ci    )
7367db96d56Sopenharmony_ci
7377db96d56Sopenharmony_ci    def create(self, **kwargs):
7387db96d56Sopenharmony_ci        return ttk.Menubutton(self.root, **kwargs)
7397db96d56Sopenharmony_ci
7407db96d56Sopenharmony_ci    def test_direction(self):
7417db96d56Sopenharmony_ci        widget = self.create()
7427db96d56Sopenharmony_ci        self.checkEnumParam(widget, 'direction',
7437db96d56Sopenharmony_ci                'above', 'below', 'left', 'right', 'flush')
7447db96d56Sopenharmony_ci
7457db96d56Sopenharmony_ci    def test_configure_menu(self):
7467db96d56Sopenharmony_ci        widget = self.create()
7477db96d56Sopenharmony_ci        menu = tkinter.Menu(widget, name='menu')
7487db96d56Sopenharmony_ci        self.checkParam(widget, 'menu', menu, conv=str)
7497db96d56Sopenharmony_ci        menu.destroy()
7507db96d56Sopenharmony_ci
7517db96d56Sopenharmony_ci
7527db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
7537db96d56Sopenharmony_ciclass ScaleTest(AbstractWidgetTest, unittest.TestCase):
7547db96d56Sopenharmony_ci    OPTIONS = (
7557db96d56Sopenharmony_ci        'class', 'command', 'cursor', 'from', 'length',
7567db96d56Sopenharmony_ci        'orient', 'style', 'takefocus', 'to', 'value', 'variable',
7577db96d56Sopenharmony_ci    )
7587db96d56Sopenharmony_ci    _conv_pixels = False
7597db96d56Sopenharmony_ci    default_orient = 'horizontal'
7607db96d56Sopenharmony_ci
7617db96d56Sopenharmony_ci    def setUp(self):
7627db96d56Sopenharmony_ci        super().setUp()
7637db96d56Sopenharmony_ci        self.scale = self.create()
7647db96d56Sopenharmony_ci        self.scale.pack()
7657db96d56Sopenharmony_ci        self.scale.update()
7667db96d56Sopenharmony_ci
7677db96d56Sopenharmony_ci    def create(self, **kwargs):
7687db96d56Sopenharmony_ci        return ttk.Scale(self.root, **kwargs)
7697db96d56Sopenharmony_ci
7707db96d56Sopenharmony_ci    def test_configure_from(self):
7717db96d56Sopenharmony_ci        widget = self.create()
7727db96d56Sopenharmony_ci        self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=False)
7737db96d56Sopenharmony_ci
7747db96d56Sopenharmony_ci    def test_configure_length(self):
7757db96d56Sopenharmony_ci        widget = self.create()
7767db96d56Sopenharmony_ci        self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
7777db96d56Sopenharmony_ci
7787db96d56Sopenharmony_ci    def test_configure_to(self):
7797db96d56Sopenharmony_ci        widget = self.create()
7807db96d56Sopenharmony_ci        self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10, conv=False)
7817db96d56Sopenharmony_ci
7827db96d56Sopenharmony_ci    def test_configure_value(self):
7837db96d56Sopenharmony_ci        widget = self.create()
7847db96d56Sopenharmony_ci        self.checkFloatParam(widget, 'value', 300, 14.9, 15.1, -10, conv=False)
7857db96d56Sopenharmony_ci
7867db96d56Sopenharmony_ci    def test_custom_event(self):
7877db96d56Sopenharmony_ci        failure = [1, 1, 1] # will need to be empty
7887db96d56Sopenharmony_ci
7897db96d56Sopenharmony_ci        funcid = self.scale.bind('<<RangeChanged>>', lambda evt: failure.pop())
7907db96d56Sopenharmony_ci
7917db96d56Sopenharmony_ci        self.scale['from'] = 10
7927db96d56Sopenharmony_ci        self.scale['from_'] = 10
7937db96d56Sopenharmony_ci        self.scale['to'] = 3
7947db96d56Sopenharmony_ci
7957db96d56Sopenharmony_ci        self.assertFalse(failure)
7967db96d56Sopenharmony_ci
7977db96d56Sopenharmony_ci        failure = [1, 1, 1]
7987db96d56Sopenharmony_ci        self.scale.configure(from_=2, to=5)
7997db96d56Sopenharmony_ci        self.scale.configure(from_=0, to=-2)
8007db96d56Sopenharmony_ci        self.scale.configure(to=10)
8017db96d56Sopenharmony_ci
8027db96d56Sopenharmony_ci        self.assertFalse(failure)
8037db96d56Sopenharmony_ci
8047db96d56Sopenharmony_ci    def test_get(self):
8057db96d56Sopenharmony_ci        if self.wantobjects:
8067db96d56Sopenharmony_ci            conv = lambda x: x
8077db96d56Sopenharmony_ci        else:
8087db96d56Sopenharmony_ci            conv = float
8097db96d56Sopenharmony_ci
8107db96d56Sopenharmony_ci        scale_width = self.scale.winfo_width()
8117db96d56Sopenharmony_ci        self.assertEqual(self.scale.get(scale_width, 0), self.scale['to'])
8127db96d56Sopenharmony_ci
8137db96d56Sopenharmony_ci        self.assertEqual(conv(self.scale.get(0, 0)), conv(self.scale['from']))
8147db96d56Sopenharmony_ci        self.assertEqual(self.scale.get(), self.scale['value'])
8157db96d56Sopenharmony_ci        self.scale['value'] = 30
8167db96d56Sopenharmony_ci        self.assertEqual(self.scale.get(), self.scale['value'])
8177db96d56Sopenharmony_ci
8187db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.scale.get, '', 0)
8197db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.scale.get, 0, '')
8207db96d56Sopenharmony_ci
8217db96d56Sopenharmony_ci    def test_set(self):
8227db96d56Sopenharmony_ci        if self.wantobjects:
8237db96d56Sopenharmony_ci            conv = lambda x: x
8247db96d56Sopenharmony_ci        else:
8257db96d56Sopenharmony_ci            conv = float
8267db96d56Sopenharmony_ci
8277db96d56Sopenharmony_ci        # set restricts the max/min values according to the current range
8287db96d56Sopenharmony_ci        max = conv(self.scale['to'])
8297db96d56Sopenharmony_ci        new_max = max + 10
8307db96d56Sopenharmony_ci        self.scale.set(new_max)
8317db96d56Sopenharmony_ci        self.assertEqual(conv(self.scale.get()), max)
8327db96d56Sopenharmony_ci        min = conv(self.scale['from'])
8337db96d56Sopenharmony_ci        self.scale.set(min - 1)
8347db96d56Sopenharmony_ci        self.assertEqual(conv(self.scale.get()), min)
8357db96d56Sopenharmony_ci
8367db96d56Sopenharmony_ci        # changing directly the variable doesn't impose this limitation tho
8377db96d56Sopenharmony_ci        var = tkinter.DoubleVar(self.root)
8387db96d56Sopenharmony_ci        self.scale['variable'] = var
8397db96d56Sopenharmony_ci        var.set(max + 5)
8407db96d56Sopenharmony_ci        self.assertEqual(conv(self.scale.get()), var.get())
8417db96d56Sopenharmony_ci        self.assertEqual(conv(self.scale.get()), max + 5)
8427db96d56Sopenharmony_ci        del var
8437db96d56Sopenharmony_ci        gc_collect()  # For PyPy or other GCs.
8447db96d56Sopenharmony_ci
8457db96d56Sopenharmony_ci        # the same happens with the value option
8467db96d56Sopenharmony_ci        self.scale['value'] = max + 10
8477db96d56Sopenharmony_ci        self.assertEqual(conv(self.scale.get()), max + 10)
8487db96d56Sopenharmony_ci        self.assertEqual(conv(self.scale.get()), conv(self.scale['value']))
8497db96d56Sopenharmony_ci
8507db96d56Sopenharmony_ci        # nevertheless, note that the max/min values we can get specifying
8517db96d56Sopenharmony_ci        # x, y coords are the ones according to the current range
8527db96d56Sopenharmony_ci        self.assertEqual(conv(self.scale.get(0, 0)), min)
8537db96d56Sopenharmony_ci        self.assertEqual(conv(self.scale.get(self.scale.winfo_width(), 0)), max)
8547db96d56Sopenharmony_ci
8557db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.scale.set, None)
8567db96d56Sopenharmony_ci
8577db96d56Sopenharmony_ci
8587db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
8597db96d56Sopenharmony_ciclass ProgressbarTest(AbstractWidgetTest, unittest.TestCase):
8607db96d56Sopenharmony_ci    OPTIONS = (
8617db96d56Sopenharmony_ci        'class', 'cursor', 'orient', 'length',
8627db96d56Sopenharmony_ci        'mode', 'maximum', 'phase',
8637db96d56Sopenharmony_ci        'style', 'takefocus', 'value', 'variable',
8647db96d56Sopenharmony_ci    )
8657db96d56Sopenharmony_ci    _conv_pixels = False
8667db96d56Sopenharmony_ci    default_orient = 'horizontal'
8677db96d56Sopenharmony_ci
8687db96d56Sopenharmony_ci    def create(self, **kwargs):
8697db96d56Sopenharmony_ci        return ttk.Progressbar(self.root, **kwargs)
8707db96d56Sopenharmony_ci
8717db96d56Sopenharmony_ci    def test_configure_length(self):
8727db96d56Sopenharmony_ci        widget = self.create()
8737db96d56Sopenharmony_ci        self.checkPixelsParam(widget, 'length', 100.1, 56.7, '2i')
8747db96d56Sopenharmony_ci
8757db96d56Sopenharmony_ci    def test_configure_maximum(self):
8767db96d56Sopenharmony_ci        widget = self.create()
8777db96d56Sopenharmony_ci        self.checkFloatParam(widget, 'maximum', 150.2, 77.7, 0, -10, conv=False)
8787db96d56Sopenharmony_ci
8797db96d56Sopenharmony_ci    def test_configure_mode(self):
8807db96d56Sopenharmony_ci        widget = self.create()
8817db96d56Sopenharmony_ci        self.checkEnumParam(widget, 'mode', 'determinate', 'indeterminate')
8827db96d56Sopenharmony_ci
8837db96d56Sopenharmony_ci    def test_configure_phase(self):
8847db96d56Sopenharmony_ci        # XXX
8857db96d56Sopenharmony_ci        pass
8867db96d56Sopenharmony_ci
8877db96d56Sopenharmony_ci    def test_configure_value(self):
8887db96d56Sopenharmony_ci        widget = self.create()
8897db96d56Sopenharmony_ci        self.checkFloatParam(widget, 'value', 150.2, 77.7, 0, -10,
8907db96d56Sopenharmony_ci                             conv=False)
8917db96d56Sopenharmony_ci
8927db96d56Sopenharmony_ci
8937db96d56Sopenharmony_ci@unittest.skipIf(sys.platform == 'darwin',
8947db96d56Sopenharmony_ci                 'ttk.Scrollbar is special on MacOSX')
8957db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
8967db96d56Sopenharmony_ciclass ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
8977db96d56Sopenharmony_ci    OPTIONS = (
8987db96d56Sopenharmony_ci        'class', 'command', 'cursor', 'orient', 'style', 'takefocus',
8997db96d56Sopenharmony_ci    )
9007db96d56Sopenharmony_ci    default_orient = 'vertical'
9017db96d56Sopenharmony_ci
9027db96d56Sopenharmony_ci    def create(self, **kwargs):
9037db96d56Sopenharmony_ci        return ttk.Scrollbar(self.root, **kwargs)
9047db96d56Sopenharmony_ci
9057db96d56Sopenharmony_ci
9067db96d56Sopenharmony_ci@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
9077db96d56Sopenharmony_ciclass NotebookTest(AbstractWidgetTest, unittest.TestCase):
9087db96d56Sopenharmony_ci    OPTIONS = (
9097db96d56Sopenharmony_ci        'class', 'cursor', 'height', 'padding', 'style', 'takefocus', 'width',
9107db96d56Sopenharmony_ci    )
9117db96d56Sopenharmony_ci
9127db96d56Sopenharmony_ci    def setUp(self):
9137db96d56Sopenharmony_ci        super().setUp()
9147db96d56Sopenharmony_ci        self.nb = self.create(padding=0)
9157db96d56Sopenharmony_ci        self.child1 = ttk.Label(self.root)
9167db96d56Sopenharmony_ci        self.child2 = ttk.Label(self.root)
9177db96d56Sopenharmony_ci        self.nb.add(self.child1, text='a')
9187db96d56Sopenharmony_ci        self.nb.add(self.child2, text='b')
9197db96d56Sopenharmony_ci
9207db96d56Sopenharmony_ci    def create(self, **kwargs):
9217db96d56Sopenharmony_ci        return ttk.Notebook(self.root, **kwargs)
9227db96d56Sopenharmony_ci
9237db96d56Sopenharmony_ci    def test_tab_identifiers(self):
9247db96d56Sopenharmony_ci        self.nb.forget(0)
9257db96d56Sopenharmony_ci        self.nb.hide(self.child2)
9267db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.tab, self.child1)
9277db96d56Sopenharmony_ci        self.assertEqual(self.nb.index('end'), 1)
9287db96d56Sopenharmony_ci        self.nb.add(self.child2)
9297db96d56Sopenharmony_ci        self.assertEqual(self.nb.index('end'), 1)
9307db96d56Sopenharmony_ci        self.nb.select(self.child2)
9317db96d56Sopenharmony_ci
9327db96d56Sopenharmony_ci        self.assertTrue(self.nb.tab('current'))
9337db96d56Sopenharmony_ci        self.nb.add(self.child1, text='a')
9347db96d56Sopenharmony_ci
9357db96d56Sopenharmony_ci        self.nb.pack()
9367db96d56Sopenharmony_ci        self.nb.update()
9377db96d56Sopenharmony_ci        if sys.platform == 'darwin':
9387db96d56Sopenharmony_ci            tb_idx = "@20,5"
9397db96d56Sopenharmony_ci        else:
9407db96d56Sopenharmony_ci            tb_idx = "@5,5"
9417db96d56Sopenharmony_ci        self.assertEqual(self.nb.tab(tb_idx), self.nb.tab('current'))
9427db96d56Sopenharmony_ci
9437db96d56Sopenharmony_ci        for i in range(5, 100, 5):
9447db96d56Sopenharmony_ci            try:
9457db96d56Sopenharmony_ci                if self.nb.tab('@%d, 5' % i, text=None) == 'a':
9467db96d56Sopenharmony_ci                    break
9477db96d56Sopenharmony_ci            except tkinter.TclError:
9487db96d56Sopenharmony_ci                pass
9497db96d56Sopenharmony_ci
9507db96d56Sopenharmony_ci        else:
9517db96d56Sopenharmony_ci            self.fail("Tab with text 'a' not found")
9527db96d56Sopenharmony_ci
9537db96d56Sopenharmony_ci    def test_add_and_hidden(self):
9547db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.hide, -1)
9557db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.hide, 'hi')
9567db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.hide, None)
9577db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.add, None)
9587db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.add, ttk.Label(self.root),
9597db96d56Sopenharmony_ci            unknown='option')
9607db96d56Sopenharmony_ci
9617db96d56Sopenharmony_ci        tabs = self.nb.tabs()
9627db96d56Sopenharmony_ci        self.nb.hide(self.child1)
9637db96d56Sopenharmony_ci        self.nb.add(self.child1)
9647db96d56Sopenharmony_ci        self.assertEqual(self.nb.tabs(), tabs)
9657db96d56Sopenharmony_ci
9667db96d56Sopenharmony_ci        child = ttk.Label(self.root)
9677db96d56Sopenharmony_ci        self.nb.add(child, text='c')
9687db96d56Sopenharmony_ci        tabs = self.nb.tabs()
9697db96d56Sopenharmony_ci
9707db96d56Sopenharmony_ci        curr = self.nb.index('current')
9717db96d56Sopenharmony_ci        # verify that the tab gets re-added at its previous position
9727db96d56Sopenharmony_ci        child2_index = self.nb.index(self.child2)
9737db96d56Sopenharmony_ci        self.nb.hide(self.child2)
9747db96d56Sopenharmony_ci        self.nb.add(self.child2)
9757db96d56Sopenharmony_ci        self.assertEqual(self.nb.tabs(), tabs)
9767db96d56Sopenharmony_ci        self.assertEqual(self.nb.index(self.child2), child2_index)
9777db96d56Sopenharmony_ci        self.assertEqual(str(self.child2), self.nb.tabs()[child2_index])
9787db96d56Sopenharmony_ci        # but the tab next to it (not hidden) is the one selected now
9797db96d56Sopenharmony_ci        self.assertEqual(self.nb.index('current'), curr + 1)
9807db96d56Sopenharmony_ci
9817db96d56Sopenharmony_ci    def test_forget(self):
9827db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.forget, -1)
9837db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.forget, 'hi')
9847db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.forget, None)
9857db96d56Sopenharmony_ci
9867db96d56Sopenharmony_ci        tabs = self.nb.tabs()
9877db96d56Sopenharmony_ci        child1_index = self.nb.index(self.child1)
9887db96d56Sopenharmony_ci        self.nb.forget(self.child1)
9897db96d56Sopenharmony_ci        self.assertNotIn(str(self.child1), self.nb.tabs())
9907db96d56Sopenharmony_ci        self.assertEqual(len(tabs) - 1, len(self.nb.tabs()))
9917db96d56Sopenharmony_ci
9927db96d56Sopenharmony_ci        self.nb.add(self.child1)
9937db96d56Sopenharmony_ci        self.assertEqual(self.nb.index(self.child1), 1)
9947db96d56Sopenharmony_ci        self.assertNotEqual(child1_index, self.nb.index(self.child1))
9957db96d56Sopenharmony_ci
9967db96d56Sopenharmony_ci    def test_index(self):
9977db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.index, -1)
9987db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.index, None)
9997db96d56Sopenharmony_ci
10007db96d56Sopenharmony_ci        self.assertIsInstance(self.nb.index('end'), int)
10017db96d56Sopenharmony_ci        self.assertEqual(self.nb.index(self.child1), 0)
10027db96d56Sopenharmony_ci        self.assertEqual(self.nb.index(self.child2), 1)
10037db96d56Sopenharmony_ci        self.assertEqual(self.nb.index('end'), 2)
10047db96d56Sopenharmony_ci
10057db96d56Sopenharmony_ci    def test_insert(self):
10067db96d56Sopenharmony_ci        # moving tabs
10077db96d56Sopenharmony_ci        tabs = self.nb.tabs()
10087db96d56Sopenharmony_ci        self.nb.insert(1, tabs[0])
10097db96d56Sopenharmony_ci        self.assertEqual(self.nb.tabs(), (tabs[1], tabs[0]))
10107db96d56Sopenharmony_ci        self.nb.insert(self.child1, self.child2)
10117db96d56Sopenharmony_ci        self.assertEqual(self.nb.tabs(), tabs)
10127db96d56Sopenharmony_ci        self.nb.insert('end', self.child1)
10137db96d56Sopenharmony_ci        self.assertEqual(self.nb.tabs(), (tabs[1], tabs[0]))
10147db96d56Sopenharmony_ci        self.nb.insert('end', 0)
10157db96d56Sopenharmony_ci        self.assertEqual(self.nb.tabs(), tabs)
10167db96d56Sopenharmony_ci        # bad moves
10177db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.insert, 2, tabs[0])
10187db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.insert, -1, tabs[0])
10197db96d56Sopenharmony_ci
10207db96d56Sopenharmony_ci        # new tab
10217db96d56Sopenharmony_ci        child3 = ttk.Label(self.root)
10227db96d56Sopenharmony_ci        self.nb.insert(1, child3)
10237db96d56Sopenharmony_ci        self.assertEqual(self.nb.tabs(), (tabs[0], str(child3), tabs[1]))
10247db96d56Sopenharmony_ci        self.nb.forget(child3)
10257db96d56Sopenharmony_ci        self.assertEqual(self.nb.tabs(), tabs)
10267db96d56Sopenharmony_ci        self.nb.insert(self.child1, child3)
10277db96d56Sopenharmony_ci        self.assertEqual(self.nb.tabs(), (str(child3), ) + tabs)
10287db96d56Sopenharmony_ci        self.nb.forget(child3)
10297db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.insert, 2, child3)
10307db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.insert, -1, child3)
10317db96d56Sopenharmony_ci
10327db96d56Sopenharmony_ci        # bad inserts
10337db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.insert, 'end', None)
10347db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.insert, None, 0)
10357db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.insert, None, None)
10367db96d56Sopenharmony_ci
10377db96d56Sopenharmony_ci    def test_select(self):
10387db96d56Sopenharmony_ci        self.nb.pack()
10397db96d56Sopenharmony_ci        self.nb.update()
10407db96d56Sopenharmony_ci
10417db96d56Sopenharmony_ci        success = []
10427db96d56Sopenharmony_ci        tab_changed = []
10437db96d56Sopenharmony_ci
10447db96d56Sopenharmony_ci        self.child1.bind('<Unmap>', lambda evt: success.append(True))
10457db96d56Sopenharmony_ci        self.nb.bind('<<NotebookTabChanged>>',
10467db96d56Sopenharmony_ci            lambda evt: tab_changed.append(True))
10477db96d56Sopenharmony_ci
10487db96d56Sopenharmony_ci        self.assertEqual(self.nb.select(), str(self.child1))
10497db96d56Sopenharmony_ci        self.nb.select(self.child2)
10507db96d56Sopenharmony_ci        self.assertTrue(success)
10517db96d56Sopenharmony_ci        self.assertEqual(self.nb.select(), str(self.child2))
10527db96d56Sopenharmony_ci
10537db96d56Sopenharmony_ci        self.nb.update()
10547db96d56Sopenharmony_ci        self.assertTrue(tab_changed)
10557db96d56Sopenharmony_ci
10567db96d56Sopenharmony_ci    def test_tab(self):
10577db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.tab, -1)
10587db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.tab, 'notab')
10597db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.nb.tab, None)
10607db96d56Sopenharmony_ci
10617db96d56Sopenharmony_ci        self.assertIsInstance(self.nb.tab(self.child1), dict)
10627db96d56Sopenharmony_ci        self.assertEqual(self.nb.tab(self.child1, text=None), 'a')
10637db96d56Sopenharmony_ci        # newer form for querying a single option
10647db96d56Sopenharmony_ci        self.assertEqual(self.nb.tab(self.child1, 'text'), 'a')
10657db96d56Sopenharmony_ci        self.nb.tab(self.child1, text='abc')
10667db96d56Sopenharmony_ci        self.assertEqual(self.nb.tab(self.child1, text=None), 'abc')
10677db96d56Sopenharmony_ci        self.assertEqual(self.nb.tab(self.child1, 'text'), 'abc')
10687db96d56Sopenharmony_ci
10697db96d56Sopenharmony_ci    def test_configure_tabs(self):
10707db96d56Sopenharmony_ci        self.assertEqual(len(self.nb.tabs()), 2)
10717db96d56Sopenharmony_ci
10727db96d56Sopenharmony_ci        self.nb.forget(self.child1)
10737db96d56Sopenharmony_ci        self.nb.forget(self.child2)
10747db96d56Sopenharmony_ci
10757db96d56Sopenharmony_ci        self.assertEqual(self.nb.tabs(), ())
10767db96d56Sopenharmony_ci
10777db96d56Sopenharmony_ci    def test_traversal(self):
10787db96d56Sopenharmony_ci        self.nb.pack()
10797db96d56Sopenharmony_ci        self.nb.update()
10807db96d56Sopenharmony_ci
10817db96d56Sopenharmony_ci        self.nb.select(0)
10827db96d56Sopenharmony_ci
10837db96d56Sopenharmony_ci        focus_identify_as = 'focus' if sys.platform != 'darwin' else ''
10847db96d56Sopenharmony_ci        self.assertEqual(self.nb.identify(5, 5), focus_identify_as)
10857db96d56Sopenharmony_ci        simulate_mouse_click(self.nb, 5, 5)
10867db96d56Sopenharmony_ci        self.nb.focus_force()
10877db96d56Sopenharmony_ci        self.nb.event_generate('<Control-Tab>')
10887db96d56Sopenharmony_ci        self.assertEqual(self.nb.select(), str(self.child2))
10897db96d56Sopenharmony_ci        self.nb.focus_force()
10907db96d56Sopenharmony_ci        self.nb.event_generate('<Shift-Control-Tab>')
10917db96d56Sopenharmony_ci        self.assertEqual(self.nb.select(), str(self.child1))
10927db96d56Sopenharmony_ci        self.nb.focus_force()
10937db96d56Sopenharmony_ci        self.nb.event_generate('<Shift-Control-Tab>')
10947db96d56Sopenharmony_ci        self.assertEqual(self.nb.select(), str(self.child2))
10957db96d56Sopenharmony_ci
10967db96d56Sopenharmony_ci        self.nb.tab(self.child1, text='a', underline=0)
10977db96d56Sopenharmony_ci        self.nb.tab(self.child2, text='e', underline=0)
10987db96d56Sopenharmony_ci        self.nb.enable_traversal()
10997db96d56Sopenharmony_ci        self.nb.focus_force()
11007db96d56Sopenharmony_ci        self.assertEqual(self.nb.identify(5, 5), focus_identify_as)
11017db96d56Sopenharmony_ci        simulate_mouse_click(self.nb, 5, 5)
11027db96d56Sopenharmony_ci        # on macOS Emacs-style keyboard shortcuts are region-dependent;
11037db96d56Sopenharmony_ci        # let's use the regular arrow keys instead
11047db96d56Sopenharmony_ci        if sys.platform == 'darwin':
11057db96d56Sopenharmony_ci            begin = '<Left>'
11067db96d56Sopenharmony_ci            end = '<Right>'
11077db96d56Sopenharmony_ci        else:
11087db96d56Sopenharmony_ci            begin = '<Alt-a>'
11097db96d56Sopenharmony_ci            end = '<Alt-e>'
11107db96d56Sopenharmony_ci        self.nb.event_generate(begin)
11117db96d56Sopenharmony_ci        self.assertEqual(self.nb.select(), str(self.child1))
11127db96d56Sopenharmony_ci        self.nb.event_generate(end)
11137db96d56Sopenharmony_ci        self.assertEqual(self.nb.select(), str(self.child2))
11147db96d56Sopenharmony_ci
11157db96d56Sopenharmony_ci
11167db96d56Sopenharmony_ci@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
11177db96d56Sopenharmony_ciclass SpinboxTest(EntryTest, unittest.TestCase):
11187db96d56Sopenharmony_ci    OPTIONS = (
11197db96d56Sopenharmony_ci        'background', 'class', 'command', 'cursor', 'exportselection',
11207db96d56Sopenharmony_ci        'font', 'foreground', 'format', 'from',  'increment',
11217db96d56Sopenharmony_ci        'invalidcommand', 'justify', 'show', 'state', 'style',
11227db96d56Sopenharmony_ci        'takefocus', 'textvariable', 'to', 'validate', 'validatecommand',
11237db96d56Sopenharmony_ci        'values', 'width', 'wrap', 'xscrollcommand',
11247db96d56Sopenharmony_ci    )
11257db96d56Sopenharmony_ci    IDENTIFY_AS = 'Spinbox.field' if sys.platform == 'darwin' else 'textarea'
11267db96d56Sopenharmony_ci
11277db96d56Sopenharmony_ci    def setUp(self):
11287db96d56Sopenharmony_ci        super().setUp()
11297db96d56Sopenharmony_ci        self.spin = self.create()
11307db96d56Sopenharmony_ci        self.spin.pack()
11317db96d56Sopenharmony_ci
11327db96d56Sopenharmony_ci    def create(self, **kwargs):
11337db96d56Sopenharmony_ci        return ttk.Spinbox(self.root, **kwargs)
11347db96d56Sopenharmony_ci
11357db96d56Sopenharmony_ci    def _click_increment_arrow(self):
11367db96d56Sopenharmony_ci        width = self.spin.winfo_width()
11377db96d56Sopenharmony_ci        height = self.spin.winfo_height()
11387db96d56Sopenharmony_ci        x = width - 5
11397db96d56Sopenharmony_ci        y = height//2 - 5
11407db96d56Sopenharmony_ci        self.assertRegex(self.spin.identify(x, y), r'.*uparrow\Z')
11417db96d56Sopenharmony_ci        self.spin.event_generate('<ButtonPress-1>', x=x, y=y)
11427db96d56Sopenharmony_ci        self.spin.event_generate('<ButtonRelease-1>', x=x, y=y)
11437db96d56Sopenharmony_ci        self.spin.update_idletasks()
11447db96d56Sopenharmony_ci
11457db96d56Sopenharmony_ci    def _click_decrement_arrow(self):
11467db96d56Sopenharmony_ci        width = self.spin.winfo_width()
11477db96d56Sopenharmony_ci        height = self.spin.winfo_height()
11487db96d56Sopenharmony_ci        x = width - 5
11497db96d56Sopenharmony_ci        y = height//2 + 4
11507db96d56Sopenharmony_ci        self.assertRegex(self.spin.identify(x, y), r'.*downarrow\Z')
11517db96d56Sopenharmony_ci        self.spin.event_generate('<ButtonPress-1>', x=x, y=y)
11527db96d56Sopenharmony_ci        self.spin.event_generate('<ButtonRelease-1>', x=x, y=y)
11537db96d56Sopenharmony_ci        self.spin.update_idletasks()
11547db96d56Sopenharmony_ci
11557db96d56Sopenharmony_ci    def test_configure_command(self):
11567db96d56Sopenharmony_ci        success = []
11577db96d56Sopenharmony_ci
11587db96d56Sopenharmony_ci        self.spin['command'] = lambda: success.append(True)
11597db96d56Sopenharmony_ci        self.spin.update()
11607db96d56Sopenharmony_ci        self._click_increment_arrow()
11617db96d56Sopenharmony_ci        self.spin.update()
11627db96d56Sopenharmony_ci        self.assertTrue(success)
11637db96d56Sopenharmony_ci
11647db96d56Sopenharmony_ci        self._click_decrement_arrow()
11657db96d56Sopenharmony_ci        self.assertEqual(len(success), 2)
11667db96d56Sopenharmony_ci
11677db96d56Sopenharmony_ci        # testing postcommand removal
11687db96d56Sopenharmony_ci        self.spin['command'] = ''
11697db96d56Sopenharmony_ci        self.spin.update_idletasks()
11707db96d56Sopenharmony_ci        self._click_increment_arrow()
11717db96d56Sopenharmony_ci        self._click_decrement_arrow()
11727db96d56Sopenharmony_ci        self.spin.update()
11737db96d56Sopenharmony_ci        self.assertEqual(len(success), 2)
11747db96d56Sopenharmony_ci
11757db96d56Sopenharmony_ci    def test_configure_to(self):
11767db96d56Sopenharmony_ci        self.spin['from'] = 0
11777db96d56Sopenharmony_ci        self.spin['to'] = 5
11787db96d56Sopenharmony_ci        self.spin.set(4)
11797db96d56Sopenharmony_ci        self.spin.update()
11807db96d56Sopenharmony_ci        self._click_increment_arrow()  # 5
11817db96d56Sopenharmony_ci
11827db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), '5')
11837db96d56Sopenharmony_ci
11847db96d56Sopenharmony_ci        self._click_increment_arrow()  # 5
11857db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), '5')
11867db96d56Sopenharmony_ci
11877db96d56Sopenharmony_ci    def test_configure_from(self):
11887db96d56Sopenharmony_ci        self.spin['from'] = 1
11897db96d56Sopenharmony_ci        self.spin['to'] = 10
11907db96d56Sopenharmony_ci        self.spin.set(2)
11917db96d56Sopenharmony_ci        self.spin.update()
11927db96d56Sopenharmony_ci        self._click_decrement_arrow()  # 1
11937db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), '1')
11947db96d56Sopenharmony_ci        self._click_decrement_arrow()  # 1
11957db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), '1')
11967db96d56Sopenharmony_ci
11977db96d56Sopenharmony_ci    def test_configure_increment(self):
11987db96d56Sopenharmony_ci        self.spin['from'] = 0
11997db96d56Sopenharmony_ci        self.spin['to'] = 10
12007db96d56Sopenharmony_ci        self.spin['increment'] = 4
12017db96d56Sopenharmony_ci        self.spin.set(1)
12027db96d56Sopenharmony_ci        self.spin.update()
12037db96d56Sopenharmony_ci
12047db96d56Sopenharmony_ci        self._click_increment_arrow()  # 5
12057db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), '5')
12067db96d56Sopenharmony_ci        self.spin['increment'] = 2
12077db96d56Sopenharmony_ci        self.spin.update()
12087db96d56Sopenharmony_ci        self._click_decrement_arrow()  # 3
12097db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), '3')
12107db96d56Sopenharmony_ci
12117db96d56Sopenharmony_ci    def test_configure_format(self):
12127db96d56Sopenharmony_ci        self.spin.set(1)
12137db96d56Sopenharmony_ci        self.spin['format'] = '%10.3f'
12147db96d56Sopenharmony_ci        self.spin.update()
12157db96d56Sopenharmony_ci        self._click_increment_arrow()
12167db96d56Sopenharmony_ci        value = self.spin.get()
12177db96d56Sopenharmony_ci
12187db96d56Sopenharmony_ci        self.assertEqual(len(value), 10)
12197db96d56Sopenharmony_ci        self.assertEqual(value.index('.'), 6)
12207db96d56Sopenharmony_ci
12217db96d56Sopenharmony_ci        self.spin['format'] = ''
12227db96d56Sopenharmony_ci        self.spin.update()
12237db96d56Sopenharmony_ci        self._click_increment_arrow()
12247db96d56Sopenharmony_ci        value = self.spin.get()
12257db96d56Sopenharmony_ci        self.assertTrue('.' not in value)
12267db96d56Sopenharmony_ci        self.assertEqual(len(value), 1)
12277db96d56Sopenharmony_ci
12287db96d56Sopenharmony_ci    def test_configure_wrap(self):
12297db96d56Sopenharmony_ci        self.spin['to'] = 10
12307db96d56Sopenharmony_ci        self.spin['from'] = 1
12317db96d56Sopenharmony_ci        self.spin.set(1)
12327db96d56Sopenharmony_ci        self.spin['wrap'] = True
12337db96d56Sopenharmony_ci        self.spin.update()
12347db96d56Sopenharmony_ci
12357db96d56Sopenharmony_ci        self._click_decrement_arrow()
12367db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), '10')
12377db96d56Sopenharmony_ci
12387db96d56Sopenharmony_ci        self._click_increment_arrow()
12397db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), '1')
12407db96d56Sopenharmony_ci
12417db96d56Sopenharmony_ci        self.spin['wrap'] = False
12427db96d56Sopenharmony_ci        self.spin.update()
12437db96d56Sopenharmony_ci
12447db96d56Sopenharmony_ci        self._click_decrement_arrow()
12457db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), '1')
12467db96d56Sopenharmony_ci
12477db96d56Sopenharmony_ci    def test_configure_values(self):
12487db96d56Sopenharmony_ci        self.assertEqual(self.spin['values'], '')
12497db96d56Sopenharmony_ci        self.checkParam(self.spin, 'values', 'mon tue wed thur',
12507db96d56Sopenharmony_ci                        expected=('mon', 'tue', 'wed', 'thur'))
12517db96d56Sopenharmony_ci        self.checkParam(self.spin, 'values', ('mon', 'tue', 'wed', 'thur'))
12527db96d56Sopenharmony_ci        self.checkParam(self.spin, 'values', (42, 3.14, '', 'any string'))
12537db96d56Sopenharmony_ci        self.checkParam(self.spin, 'values', '')
12547db96d56Sopenharmony_ci
12557db96d56Sopenharmony_ci        self.spin['values'] = ['a', 1, 'c']
12567db96d56Sopenharmony_ci
12577db96d56Sopenharmony_ci        # test incrementing / decrementing values
12587db96d56Sopenharmony_ci        self.spin.set('a')
12597db96d56Sopenharmony_ci        self.spin.update()
12607db96d56Sopenharmony_ci        self._click_increment_arrow()
12617db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), '1')
12627db96d56Sopenharmony_ci
12637db96d56Sopenharmony_ci        self._click_decrement_arrow()
12647db96d56Sopenharmony_ci        self.assertEqual(self.spin.get(), 'a')
12657db96d56Sopenharmony_ci
12667db96d56Sopenharmony_ci        # testing values with empty string set through configure
12677db96d56Sopenharmony_ci        self.spin.configure(values=[1, '', 2])
12687db96d56Sopenharmony_ci        self.assertEqual(self.spin['values'],
12697db96d56Sopenharmony_ci                         ('1', '', '2') if self.wantobjects else
12707db96d56Sopenharmony_ci                         '1 {} 2')
12717db96d56Sopenharmony_ci
12727db96d56Sopenharmony_ci        # testing values with spaces
12737db96d56Sopenharmony_ci        self.spin['values'] = ['a b', 'a\tb', 'a\nb']
12747db96d56Sopenharmony_ci        self.assertEqual(self.spin['values'],
12757db96d56Sopenharmony_ci                         ('a b', 'a\tb', 'a\nb') if self.wantobjects else
12767db96d56Sopenharmony_ci                         '{a b} {a\tb} {a\nb}')
12777db96d56Sopenharmony_ci
12787db96d56Sopenharmony_ci        # testing values with special characters
12797db96d56Sopenharmony_ci        self.spin['values'] = [r'a\tb', '"a"', '} {']
12807db96d56Sopenharmony_ci        self.assertEqual(self.spin['values'],
12817db96d56Sopenharmony_ci                         (r'a\tb', '"a"', '} {') if self.wantobjects else
12827db96d56Sopenharmony_ci                         r'a\\tb {"a"} \}\ \{')
12837db96d56Sopenharmony_ci
12847db96d56Sopenharmony_ci        # testing creating spinbox with empty string in values
12857db96d56Sopenharmony_ci        spin2 = ttk.Spinbox(self.root, values=[1, 2, ''])
12867db96d56Sopenharmony_ci        self.assertEqual(spin2['values'],
12877db96d56Sopenharmony_ci                         ('1', '2', '') if self.wantobjects else '1 2 {}')
12887db96d56Sopenharmony_ci        spin2.destroy()
12897db96d56Sopenharmony_ci
12907db96d56Sopenharmony_ci
12917db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
12927db96d56Sopenharmony_ciclass TreeviewTest(AbstractWidgetTest, unittest.TestCase):
12937db96d56Sopenharmony_ci    OPTIONS = (
12947db96d56Sopenharmony_ci        'class', 'columns', 'cursor', 'displaycolumns',
12957db96d56Sopenharmony_ci        'height', 'padding', 'selectmode', 'show',
12967db96d56Sopenharmony_ci        'style', 'takefocus', 'xscrollcommand', 'yscrollcommand',
12977db96d56Sopenharmony_ci    )
12987db96d56Sopenharmony_ci
12997db96d56Sopenharmony_ci    def setUp(self):
13007db96d56Sopenharmony_ci        super().setUp()
13017db96d56Sopenharmony_ci        self.tv = self.create(padding=0)
13027db96d56Sopenharmony_ci
13037db96d56Sopenharmony_ci    def create(self, **kwargs):
13047db96d56Sopenharmony_ci        return ttk.Treeview(self.root, **kwargs)
13057db96d56Sopenharmony_ci
13067db96d56Sopenharmony_ci    def test_configure_columns(self):
13077db96d56Sopenharmony_ci        widget = self.create()
13087db96d56Sopenharmony_ci        self.checkParam(widget, 'columns', 'a b c',
13097db96d56Sopenharmony_ci                        expected=('a', 'b', 'c'))
13107db96d56Sopenharmony_ci        self.checkParam(widget, 'columns', ('a', 'b', 'c'))
13117db96d56Sopenharmony_ci        self.checkParam(widget, 'columns', '')
13127db96d56Sopenharmony_ci
13137db96d56Sopenharmony_ci    def test_configure_displaycolumns(self):
13147db96d56Sopenharmony_ci        widget = self.create()
13157db96d56Sopenharmony_ci        widget['columns'] = ('a', 'b', 'c')
13167db96d56Sopenharmony_ci        self.checkParam(widget, 'displaycolumns', 'b a c',
13177db96d56Sopenharmony_ci                        expected=('b', 'a', 'c'))
13187db96d56Sopenharmony_ci        self.checkParam(widget, 'displaycolumns', ('b', 'a', 'c'))
13197db96d56Sopenharmony_ci        self.checkParam(widget, 'displaycolumns', '#all',
13207db96d56Sopenharmony_ci                        expected=('#all',))
13217db96d56Sopenharmony_ci        self.checkParam(widget, 'displaycolumns', (2, 1, 0))
13227db96d56Sopenharmony_ci        self.checkInvalidParam(widget, 'displaycolumns', ('a', 'b', 'd'),
13237db96d56Sopenharmony_ci                               errmsg='Invalid column index d')
13247db96d56Sopenharmony_ci        self.checkInvalidParam(widget, 'displaycolumns', (1, 2, 3),
13257db96d56Sopenharmony_ci                               errmsg='Column index 3 out of bounds')
13267db96d56Sopenharmony_ci        self.checkInvalidParam(widget, 'displaycolumns', (1, -2),
13277db96d56Sopenharmony_ci                               errmsg='Column index -2 out of bounds')
13287db96d56Sopenharmony_ci
13297db96d56Sopenharmony_ci    def test_configure_height(self):
13307db96d56Sopenharmony_ci        widget = self.create()
13317db96d56Sopenharmony_ci        self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False)
13327db96d56Sopenharmony_ci        self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=False)
13337db96d56Sopenharmony_ci
13347db96d56Sopenharmony_ci    def test_configure_selectmode(self):
13357db96d56Sopenharmony_ci        widget = self.create()
13367db96d56Sopenharmony_ci        self.checkEnumParam(widget, 'selectmode',
13377db96d56Sopenharmony_ci                            'none', 'browse', 'extended')
13387db96d56Sopenharmony_ci
13397db96d56Sopenharmony_ci    def test_configure_show(self):
13407db96d56Sopenharmony_ci        widget = self.create()
13417db96d56Sopenharmony_ci        self.checkParam(widget, 'show', 'tree headings',
13427db96d56Sopenharmony_ci                        expected=('tree', 'headings'))
13437db96d56Sopenharmony_ci        self.checkParam(widget, 'show', ('tree', 'headings'))
13447db96d56Sopenharmony_ci        self.checkParam(widget, 'show', ('headings', 'tree'))
13457db96d56Sopenharmony_ci        self.checkParam(widget, 'show', 'tree', expected=('tree',))
13467db96d56Sopenharmony_ci        self.checkParam(widget, 'show', 'headings', expected=('headings',))
13477db96d56Sopenharmony_ci
13487db96d56Sopenharmony_ci    def test_bbox(self):
13497db96d56Sopenharmony_ci        self.tv.pack()
13507db96d56Sopenharmony_ci        self.assertEqual(self.tv.bbox(''), '')
13517db96d56Sopenharmony_ci        self.tv.update()
13527db96d56Sopenharmony_ci
13537db96d56Sopenharmony_ci        item_id = self.tv.insert('', 'end')
13547db96d56Sopenharmony_ci        children = self.tv.get_children()
13557db96d56Sopenharmony_ci        self.assertTrue(children)
13567db96d56Sopenharmony_ci
13577db96d56Sopenharmony_ci        bbox = self.tv.bbox(children[0])
13587db96d56Sopenharmony_ci        self.assertIsBoundingBox(bbox)
13597db96d56Sopenharmony_ci
13607db96d56Sopenharmony_ci        # compare width in bboxes
13617db96d56Sopenharmony_ci        self.tv['columns'] = ['test']
13627db96d56Sopenharmony_ci        self.tv.column('test', width=50)
13637db96d56Sopenharmony_ci        bbox_column0 = self.tv.bbox(children[0], 0)
13647db96d56Sopenharmony_ci        root_width = self.tv.column('#0', width=None)
13657db96d56Sopenharmony_ci        if not self.wantobjects:
13667db96d56Sopenharmony_ci            root_width = int(root_width)
13677db96d56Sopenharmony_ci        self.assertEqual(bbox_column0[0], bbox[0] + root_width)
13687db96d56Sopenharmony_ci
13697db96d56Sopenharmony_ci        # verify that bbox of a closed item is the empty string
13707db96d56Sopenharmony_ci        child1 = self.tv.insert(item_id, 'end')
13717db96d56Sopenharmony_ci        self.assertEqual(self.tv.bbox(child1), '')
13727db96d56Sopenharmony_ci
13737db96d56Sopenharmony_ci    def test_children(self):
13747db96d56Sopenharmony_ci        # no children yet, should get an empty tuple
13757db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(), ())
13767db96d56Sopenharmony_ci
13777db96d56Sopenharmony_ci        item_id = self.tv.insert('', 'end')
13787db96d56Sopenharmony_ci        self.assertIsInstance(self.tv.get_children(), tuple)
13797db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children()[0], item_id)
13807db96d56Sopenharmony_ci
13817db96d56Sopenharmony_ci        # add item_id and child3 as children of child2
13827db96d56Sopenharmony_ci        child2 = self.tv.insert('', 'end')
13837db96d56Sopenharmony_ci        child3 = self.tv.insert('', 'end')
13847db96d56Sopenharmony_ci        self.tv.set_children(child2, item_id, child3)
13857db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(child2), (item_id, child3))
13867db96d56Sopenharmony_ci
13877db96d56Sopenharmony_ci        # child3 has child2 as parent, thus trying to set child2 as a children
13887db96d56Sopenharmony_ci        # of child3 should result in an error
13897db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError,
13907db96d56Sopenharmony_ci            self.tv.set_children, child3, child2)
13917db96d56Sopenharmony_ci
13927db96d56Sopenharmony_ci        # remove child2 children
13937db96d56Sopenharmony_ci        self.tv.set_children(child2)
13947db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(child2), ())
13957db96d56Sopenharmony_ci
13967db96d56Sopenharmony_ci        # remove root's children
13977db96d56Sopenharmony_ci        self.tv.set_children('')
13987db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(), ())
13997db96d56Sopenharmony_ci
14007db96d56Sopenharmony_ci    def test_column(self):
14017db96d56Sopenharmony_ci        # return a dict with all options/values
14027db96d56Sopenharmony_ci        self.assertIsInstance(self.tv.column('#0'), dict)
14037db96d56Sopenharmony_ci        # return a single value of the given option
14047db96d56Sopenharmony_ci        if self.wantobjects:
14057db96d56Sopenharmony_ci            self.assertIsInstance(self.tv.column('#0', width=None), int)
14067db96d56Sopenharmony_ci        # set a new value for an option
14077db96d56Sopenharmony_ci        self.tv.column('#0', width=10)
14087db96d56Sopenharmony_ci        # testing new way to get option value
14097db96d56Sopenharmony_ci        self.assertEqual(self.tv.column('#0', 'width'),
14107db96d56Sopenharmony_ci                         10 if self.wantobjects else '10')
14117db96d56Sopenharmony_ci        self.assertEqual(self.tv.column('#0', width=None),
14127db96d56Sopenharmony_ci                         10 if self.wantobjects else '10')
14137db96d56Sopenharmony_ci        # check read-only option
14147db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.column, '#0', id='X')
14157db96d56Sopenharmony_ci
14167db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.column, 'invalid')
14177db96d56Sopenharmony_ci        invalid_kws = [
14187db96d56Sopenharmony_ci            {'unknown_option': 'some value'},  {'stretch': 'wrong'},
14197db96d56Sopenharmony_ci            {'anchor': 'wrong'}, {'width': 'wrong'}, {'minwidth': 'wrong'}
14207db96d56Sopenharmony_ci        ]
14217db96d56Sopenharmony_ci        for kw in invalid_kws:
14227db96d56Sopenharmony_ci            self.assertRaises(tkinter.TclError, self.tv.column, '#0',
14237db96d56Sopenharmony_ci                **kw)
14247db96d56Sopenharmony_ci
14257db96d56Sopenharmony_ci    def test_delete(self):
14267db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.delete, '#0')
14277db96d56Sopenharmony_ci
14287db96d56Sopenharmony_ci        item_id = self.tv.insert('', 'end')
14297db96d56Sopenharmony_ci        item2 = self.tv.insert(item_id, 'end')
14307db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(), (item_id, ))
14317db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(item_id), (item2, ))
14327db96d56Sopenharmony_ci
14337db96d56Sopenharmony_ci        self.tv.delete(item_id)
14347db96d56Sopenharmony_ci        self.assertFalse(self.tv.get_children())
14357db96d56Sopenharmony_ci
14367db96d56Sopenharmony_ci        # reattach should fail
14377db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError,
14387db96d56Sopenharmony_ci            self.tv.reattach, item_id, '', 'end')
14397db96d56Sopenharmony_ci
14407db96d56Sopenharmony_ci        # test multiple item delete
14417db96d56Sopenharmony_ci        item1 = self.tv.insert('', 'end')
14427db96d56Sopenharmony_ci        item2 = self.tv.insert('', 'end')
14437db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(), (item1, item2))
14447db96d56Sopenharmony_ci
14457db96d56Sopenharmony_ci        self.tv.delete(item1, item2)
14467db96d56Sopenharmony_ci        self.assertFalse(self.tv.get_children())
14477db96d56Sopenharmony_ci
14487db96d56Sopenharmony_ci    def test_detach_reattach(self):
14497db96d56Sopenharmony_ci        item_id = self.tv.insert('', 'end')
14507db96d56Sopenharmony_ci        item2 = self.tv.insert(item_id, 'end')
14517db96d56Sopenharmony_ci
14527db96d56Sopenharmony_ci        # calling detach without items is valid, although it does nothing
14537db96d56Sopenharmony_ci        prev = self.tv.get_children()
14547db96d56Sopenharmony_ci        self.tv.detach() # this should do nothing
14557db96d56Sopenharmony_ci        self.assertEqual(prev, self.tv.get_children())
14567db96d56Sopenharmony_ci
14577db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(), (item_id, ))
14587db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(item_id), (item2, ))
14597db96d56Sopenharmony_ci
14607db96d56Sopenharmony_ci        # detach item with children
14617db96d56Sopenharmony_ci        self.tv.detach(item_id)
14627db96d56Sopenharmony_ci        self.assertFalse(self.tv.get_children())
14637db96d56Sopenharmony_ci
14647db96d56Sopenharmony_ci        # reattach item with children
14657db96d56Sopenharmony_ci        self.tv.reattach(item_id, '', 'end')
14667db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(), (item_id, ))
14677db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(item_id), (item2, ))
14687db96d56Sopenharmony_ci
14697db96d56Sopenharmony_ci        # move a children to the root
14707db96d56Sopenharmony_ci        self.tv.move(item2, '', 'end')
14717db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(), (item_id, item2))
14727db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(item_id), ())
14737db96d56Sopenharmony_ci
14747db96d56Sopenharmony_ci        # bad values
14757db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError,
14767db96d56Sopenharmony_ci            self.tv.reattach, 'nonexistent', '', 'end')
14777db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError,
14787db96d56Sopenharmony_ci            self.tv.detach, 'nonexistent')
14797db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError,
14807db96d56Sopenharmony_ci            self.tv.reattach, item2, 'otherparent', 'end')
14817db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError,
14827db96d56Sopenharmony_ci            self.tv.reattach, item2, '', 'invalid')
14837db96d56Sopenharmony_ci
14847db96d56Sopenharmony_ci        # multiple detach
14857db96d56Sopenharmony_ci        self.tv.detach(item_id, item2)
14867db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(), ())
14877db96d56Sopenharmony_ci        self.assertEqual(self.tv.get_children(item_id), ())
14887db96d56Sopenharmony_ci
14897db96d56Sopenharmony_ci    def test_exists(self):
14907db96d56Sopenharmony_ci        self.assertEqual(self.tv.exists('something'), False)
14917db96d56Sopenharmony_ci        self.assertEqual(self.tv.exists(''), True)
14927db96d56Sopenharmony_ci        self.assertEqual(self.tv.exists({}), False)
14937db96d56Sopenharmony_ci
14947db96d56Sopenharmony_ci        # the following will make a tk.call equivalent to
14957db96d56Sopenharmony_ci        # tk.call(treeview, "exists") which should result in an error
14967db96d56Sopenharmony_ci        # in the tcl interpreter since tk requires an item.
14977db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.exists, None)
14987db96d56Sopenharmony_ci
14997db96d56Sopenharmony_ci    def test_focus(self):
15007db96d56Sopenharmony_ci        # nothing is focused right now
15017db96d56Sopenharmony_ci        self.assertEqual(self.tv.focus(), '')
15027db96d56Sopenharmony_ci
15037db96d56Sopenharmony_ci        item1 = self.tv.insert('', 'end')
15047db96d56Sopenharmony_ci        self.tv.focus(item1)
15057db96d56Sopenharmony_ci        self.assertEqual(self.tv.focus(), item1)
15067db96d56Sopenharmony_ci
15077db96d56Sopenharmony_ci        self.tv.delete(item1)
15087db96d56Sopenharmony_ci        self.assertEqual(self.tv.focus(), '')
15097db96d56Sopenharmony_ci
15107db96d56Sopenharmony_ci        # try focusing inexistent item
15117db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.focus, 'hi')
15127db96d56Sopenharmony_ci
15137db96d56Sopenharmony_ci    def test_heading(self):
15147db96d56Sopenharmony_ci        # check a dict is returned
15157db96d56Sopenharmony_ci        self.assertIsInstance(self.tv.heading('#0'), dict)
15167db96d56Sopenharmony_ci
15177db96d56Sopenharmony_ci        # check a value is returned
15187db96d56Sopenharmony_ci        self.tv.heading('#0', text='hi')
15197db96d56Sopenharmony_ci        self.assertEqual(self.tv.heading('#0', 'text'), 'hi')
15207db96d56Sopenharmony_ci        self.assertEqual(self.tv.heading('#0', text=None), 'hi')
15217db96d56Sopenharmony_ci
15227db96d56Sopenharmony_ci        # invalid option
15237db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.heading, '#0',
15247db96d56Sopenharmony_ci            background=None)
15257db96d56Sopenharmony_ci        # invalid value
15267db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.heading, '#0',
15277db96d56Sopenharmony_ci            anchor=1)
15287db96d56Sopenharmony_ci
15297db96d56Sopenharmony_ci    def test_heading_callback(self):
15307db96d56Sopenharmony_ci        def simulate_heading_click(x, y):
15317db96d56Sopenharmony_ci            if tcl_version >= (8, 6):
15327db96d56Sopenharmony_ci                self.assertEqual(self.tv.identify_column(x), '#0')
15337db96d56Sopenharmony_ci                self.assertEqual(self.tv.identify_region(x, y), 'heading')
15347db96d56Sopenharmony_ci            simulate_mouse_click(self.tv, x, y)
15357db96d56Sopenharmony_ci            self.tv.update()
15367db96d56Sopenharmony_ci
15377db96d56Sopenharmony_ci        success = [] # no success for now
15387db96d56Sopenharmony_ci
15397db96d56Sopenharmony_ci        self.tv.pack()
15407db96d56Sopenharmony_ci        self.tv.heading('#0', command=lambda: success.append(True))
15417db96d56Sopenharmony_ci        self.tv.column('#0', width=100)
15427db96d56Sopenharmony_ci        self.tv.update()
15437db96d56Sopenharmony_ci
15447db96d56Sopenharmony_ci        # assuming that the coords (5, 5) fall into heading #0
15457db96d56Sopenharmony_ci        simulate_heading_click(5, 5)
15467db96d56Sopenharmony_ci        if not success:
15477db96d56Sopenharmony_ci            self.fail("The command associated to the treeview heading wasn't "
15487db96d56Sopenharmony_ci                "invoked.")
15497db96d56Sopenharmony_ci
15507db96d56Sopenharmony_ci        success = []
15517db96d56Sopenharmony_ci        commands = self.tv.master._tclCommands
15527db96d56Sopenharmony_ci        self.tv.heading('#0', command=str(self.tv.heading('#0', command=None)))
15537db96d56Sopenharmony_ci        self.assertEqual(commands, self.tv.master._tclCommands)
15547db96d56Sopenharmony_ci        simulate_heading_click(5, 5)
15557db96d56Sopenharmony_ci        if not success:
15567db96d56Sopenharmony_ci            self.fail("The command associated to the treeview heading wasn't "
15577db96d56Sopenharmony_ci                "invoked.")
15587db96d56Sopenharmony_ci
15597db96d56Sopenharmony_ci        # XXX The following raises an error in a tcl interpreter, but not in
15607db96d56Sopenharmony_ci        # Python
15617db96d56Sopenharmony_ci        #self.tv.heading('#0', command='I dont exist')
15627db96d56Sopenharmony_ci        #simulate_heading_click(5, 5)
15637db96d56Sopenharmony_ci
15647db96d56Sopenharmony_ci    def test_index(self):
15657db96d56Sopenharmony_ci        # item 'what' doesn't exist
15667db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.index, 'what')
15677db96d56Sopenharmony_ci
15687db96d56Sopenharmony_ci        self.assertEqual(self.tv.index(''), 0)
15697db96d56Sopenharmony_ci
15707db96d56Sopenharmony_ci        item1 = self.tv.insert('', 'end')
15717db96d56Sopenharmony_ci        item2 = self.tv.insert('', 'end')
15727db96d56Sopenharmony_ci        c1 = self.tv.insert(item1, 'end')
15737db96d56Sopenharmony_ci        c2 = self.tv.insert(item1, 'end')
15747db96d56Sopenharmony_ci        self.assertEqual(self.tv.index(item1), 0)
15757db96d56Sopenharmony_ci        self.assertEqual(self.tv.index(c1), 0)
15767db96d56Sopenharmony_ci        self.assertEqual(self.tv.index(c2), 1)
15777db96d56Sopenharmony_ci        self.assertEqual(self.tv.index(item2), 1)
15787db96d56Sopenharmony_ci
15797db96d56Sopenharmony_ci        self.tv.move(item2, '', 0)
15807db96d56Sopenharmony_ci        self.assertEqual(self.tv.index(item2), 0)
15817db96d56Sopenharmony_ci        self.assertEqual(self.tv.index(item1), 1)
15827db96d56Sopenharmony_ci
15837db96d56Sopenharmony_ci        # check that index still works even after its parent and siblings
15847db96d56Sopenharmony_ci        # have been detached
15857db96d56Sopenharmony_ci        self.tv.detach(item1)
15867db96d56Sopenharmony_ci        self.assertEqual(self.tv.index(c2), 1)
15877db96d56Sopenharmony_ci        self.tv.detach(c1)
15887db96d56Sopenharmony_ci        self.assertEqual(self.tv.index(c2), 0)
15897db96d56Sopenharmony_ci
15907db96d56Sopenharmony_ci        # but it fails after item has been deleted
15917db96d56Sopenharmony_ci        self.tv.delete(item1)
15927db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.index, c2)
15937db96d56Sopenharmony_ci
15947db96d56Sopenharmony_ci    def test_insert_item(self):
15957db96d56Sopenharmony_ci        # parent 'none' doesn't exist
15967db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.insert, 'none', 'end')
15977db96d56Sopenharmony_ci
15987db96d56Sopenharmony_ci        # open values
15997db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end',
16007db96d56Sopenharmony_ci            open='')
16017db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end',
16027db96d56Sopenharmony_ci            open='please')
16037db96d56Sopenharmony_ci        self.assertFalse(self.tv.delete(self.tv.insert('', 'end', open=True)))
16047db96d56Sopenharmony_ci        self.assertFalse(self.tv.delete(self.tv.insert('', 'end', open=False)))
16057db96d56Sopenharmony_ci
16067db96d56Sopenharmony_ci        # invalid index
16077db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.insert, '', 'middle')
16087db96d56Sopenharmony_ci
16097db96d56Sopenharmony_ci        # trying to duplicate item id is invalid
16107db96d56Sopenharmony_ci        itemid = self.tv.insert('', 'end', 'first-item')
16117db96d56Sopenharmony_ci        self.assertEqual(itemid, 'first-item')
16127db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end',
16137db96d56Sopenharmony_ci            'first-item')
16147db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end',
16157db96d56Sopenharmony_ci            MockTclObj('first-item'))
16167db96d56Sopenharmony_ci
16177db96d56Sopenharmony_ci        # unicode values
16187db96d56Sopenharmony_ci        value = '\xe1ba'
16197db96d56Sopenharmony_ci        item = self.tv.insert('', 'end', values=(value, ))
16207db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(item, 'values'),
16217db96d56Sopenharmony_ci                         (value,) if self.wantobjects else value)
16227db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(item, values=None),
16237db96d56Sopenharmony_ci                         (value,) if self.wantobjects else value)
16247db96d56Sopenharmony_ci
16257db96d56Sopenharmony_ci        self.tv.item(item, values=self.root.splitlist(self.tv.item(item, values=None)))
16267db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(item, values=None),
16277db96d56Sopenharmony_ci                         (value,) if self.wantobjects else value)
16287db96d56Sopenharmony_ci
16297db96d56Sopenharmony_ci        self.assertIsInstance(self.tv.item(item), dict)
16307db96d56Sopenharmony_ci
16317db96d56Sopenharmony_ci        # erase item values
16327db96d56Sopenharmony_ci        self.tv.item(item, values='')
16337db96d56Sopenharmony_ci        self.assertFalse(self.tv.item(item, values=None))
16347db96d56Sopenharmony_ci
16357db96d56Sopenharmony_ci        # item tags
16367db96d56Sopenharmony_ci        item = self.tv.insert('', 'end', tags=[1, 2, value])
16377db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(item, tags=None),
16387db96d56Sopenharmony_ci                         ('1', '2', value) if self.wantobjects else
16397db96d56Sopenharmony_ci                         '1 2 %s' % value)
16407db96d56Sopenharmony_ci        self.tv.item(item, tags=[])
16417db96d56Sopenharmony_ci        self.assertFalse(self.tv.item(item, tags=None))
16427db96d56Sopenharmony_ci        self.tv.item(item, tags=(1, 2))
16437db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(item, tags=None),
16447db96d56Sopenharmony_ci                         ('1', '2') if self.wantobjects else '1 2')
16457db96d56Sopenharmony_ci
16467db96d56Sopenharmony_ci        # values with spaces
16477db96d56Sopenharmony_ci        item = self.tv.insert('', 'end', values=('a b c',
16487db96d56Sopenharmony_ci            '%s %s' % (value, value)))
16497db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(item, values=None),
16507db96d56Sopenharmony_ci            ('a b c', '%s %s' % (value, value)) if self.wantobjects else
16517db96d56Sopenharmony_ci            '{a b c} {%s %s}' % (value, value))
16527db96d56Sopenharmony_ci
16537db96d56Sopenharmony_ci        # text
16547db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(
16557db96d56Sopenharmony_ci            self.tv.insert('', 'end', text="Label here"), text=None),
16567db96d56Sopenharmony_ci            "Label here")
16577db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(
16587db96d56Sopenharmony_ci            self.tv.insert('', 'end', text=value), text=None),
16597db96d56Sopenharmony_ci            value)
16607db96d56Sopenharmony_ci
16617db96d56Sopenharmony_ci        # test for values which are not None
16627db96d56Sopenharmony_ci        itemid = self.tv.insert('', 'end', 0)
16637db96d56Sopenharmony_ci        self.assertEqual(itemid, '0')
16647db96d56Sopenharmony_ci        itemid = self.tv.insert('', 'end', 0.0)
16657db96d56Sopenharmony_ci        self.assertEqual(itemid, '0.0')
16667db96d56Sopenharmony_ci        # this is because False resolves to 0 and element with 0 iid is already present
16677db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', False)
16687db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', '')
16697db96d56Sopenharmony_ci
16707db96d56Sopenharmony_ci    def test_selection(self):
16717db96d56Sopenharmony_ci        self.assertRaises(TypeError, self.tv.selection, 'spam')
16727db96d56Sopenharmony_ci        # item 'none' doesn't exist
16737db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.selection_set, 'none')
16747db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.selection_add, 'none')
16757db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.selection_remove, 'none')
16767db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.selection_toggle, 'none')
16777db96d56Sopenharmony_ci
16787db96d56Sopenharmony_ci        item1 = self.tv.insert('', 'end')
16797db96d56Sopenharmony_ci        item2 = self.tv.insert('', 'end')
16807db96d56Sopenharmony_ci        c1 = self.tv.insert(item1, 'end')
16817db96d56Sopenharmony_ci        c2 = self.tv.insert(item1, 'end')
16827db96d56Sopenharmony_ci        c3 = self.tv.insert(item1, 'end')
16837db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), ())
16847db96d56Sopenharmony_ci
16857db96d56Sopenharmony_ci        self.tv.selection_set(c1, item2)
16867db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c1, item2))
16877db96d56Sopenharmony_ci        self.tv.selection_set(c2)
16887db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c2,))
16897db96d56Sopenharmony_ci
16907db96d56Sopenharmony_ci        self.tv.selection_add(c1, item2)
16917db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c1, c2, item2))
16927db96d56Sopenharmony_ci        self.tv.selection_add(item1)
16937db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (item1, c1, c2, item2))
16947db96d56Sopenharmony_ci        self.tv.selection_add()
16957db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (item1, c1, c2, item2))
16967db96d56Sopenharmony_ci
16977db96d56Sopenharmony_ci        self.tv.selection_remove(item1, c3)
16987db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c1, c2, item2))
16997db96d56Sopenharmony_ci        self.tv.selection_remove(c2)
17007db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c1, item2))
17017db96d56Sopenharmony_ci        self.tv.selection_remove()
17027db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c1, item2))
17037db96d56Sopenharmony_ci
17047db96d56Sopenharmony_ci        self.tv.selection_toggle(c1, c3)
17057db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c3, item2))
17067db96d56Sopenharmony_ci        self.tv.selection_toggle(item2)
17077db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c3,))
17087db96d56Sopenharmony_ci        self.tv.selection_toggle()
17097db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c3,))
17107db96d56Sopenharmony_ci
17117db96d56Sopenharmony_ci        self.tv.insert('', 'end', id='with spaces')
17127db96d56Sopenharmony_ci        self.tv.selection_set('with spaces')
17137db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), ('with spaces',))
17147db96d56Sopenharmony_ci
17157db96d56Sopenharmony_ci        self.tv.insert('', 'end', id='{brace')
17167db96d56Sopenharmony_ci        self.tv.selection_set('{brace')
17177db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), ('{brace',))
17187db96d56Sopenharmony_ci
17197db96d56Sopenharmony_ci        self.tv.insert('', 'end', id='unicode\u20ac')
17207db96d56Sopenharmony_ci        self.tv.selection_set('unicode\u20ac')
17217db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), ('unicode\u20ac',))
17227db96d56Sopenharmony_ci
17237db96d56Sopenharmony_ci        self.tv.insert('', 'end', id=b'bytes\xe2\x82\xac')
17247db96d56Sopenharmony_ci        self.tv.selection_set(b'bytes\xe2\x82\xac')
17257db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), ('bytes\xe2\x82\xac',))
17267db96d56Sopenharmony_ci
17277db96d56Sopenharmony_ci        self.tv.selection_set()
17287db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), ())
17297db96d56Sopenharmony_ci
17307db96d56Sopenharmony_ci        # Old interface
17317db96d56Sopenharmony_ci        self.tv.selection_set((c1, item2))
17327db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c1, item2))
17337db96d56Sopenharmony_ci        self.tv.selection_add((c1, item1))
17347db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (item1, c1, item2))
17357db96d56Sopenharmony_ci        self.tv.selection_remove((item1, c3))
17367db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c1, item2))
17377db96d56Sopenharmony_ci        self.tv.selection_toggle((c1, c3))
17387db96d56Sopenharmony_ci        self.assertEqual(self.tv.selection(), (c3, item2))
17397db96d56Sopenharmony_ci
17407db96d56Sopenharmony_ci    def test_set(self):
17417db96d56Sopenharmony_ci        self.tv['columns'] = ['A', 'B']
17427db96d56Sopenharmony_ci        item = self.tv.insert('', 'end', values=['a', 'b'])
17437db96d56Sopenharmony_ci        self.assertEqual(self.tv.set(item), {'A': 'a', 'B': 'b'})
17447db96d56Sopenharmony_ci
17457db96d56Sopenharmony_ci        self.tv.set(item, 'B', 'a')
17467db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(item, values=None),
17477db96d56Sopenharmony_ci                         ('a', 'a') if self.wantobjects else 'a a')
17487db96d56Sopenharmony_ci
17497db96d56Sopenharmony_ci        self.tv['columns'] = ['B']
17507db96d56Sopenharmony_ci        self.assertEqual(self.tv.set(item), {'B': 'a'})
17517db96d56Sopenharmony_ci
17527db96d56Sopenharmony_ci        self.tv.set(item, 'B', 'b')
17537db96d56Sopenharmony_ci        self.assertEqual(self.tv.set(item, column='B'), 'b')
17547db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(item, values=None),
17557db96d56Sopenharmony_ci                         ('b', 'a') if self.wantobjects else 'b a')
17567db96d56Sopenharmony_ci
17577db96d56Sopenharmony_ci        self.tv.set(item, 'B', 123)
17587db96d56Sopenharmony_ci        self.assertEqual(self.tv.set(item, 'B'),
17597db96d56Sopenharmony_ci                         123 if self.wantobjects else '123')
17607db96d56Sopenharmony_ci        self.assertEqual(self.tv.item(item, values=None),
17617db96d56Sopenharmony_ci                         (123, 'a') if self.wantobjects else '123 a')
17627db96d56Sopenharmony_ci        self.assertEqual(self.tv.set(item),
17637db96d56Sopenharmony_ci                         {'B': 123} if self.wantobjects else {'B': '123'})
17647db96d56Sopenharmony_ci
17657db96d56Sopenharmony_ci        # inexistent column
17667db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.set, item, 'A')
17677db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.set, item, 'A', 'b')
17687db96d56Sopenharmony_ci
17697db96d56Sopenharmony_ci        # inexistent item
17707db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.set, 'notme')
17717db96d56Sopenharmony_ci
17727db96d56Sopenharmony_ci    def test_tag_bind(self):
17737db96d56Sopenharmony_ci        events = []
17747db96d56Sopenharmony_ci        item1 = self.tv.insert('', 'end', tags=['call'])
17757db96d56Sopenharmony_ci        item2 = self.tv.insert('', 'end', tags=['call'])
17767db96d56Sopenharmony_ci        self.tv.tag_bind('call', '<ButtonPress-1>',
17777db96d56Sopenharmony_ci            lambda evt: events.append(1))
17787db96d56Sopenharmony_ci        self.tv.tag_bind('call', '<ButtonRelease-1>',
17797db96d56Sopenharmony_ci            lambda evt: events.append(2))
17807db96d56Sopenharmony_ci
17817db96d56Sopenharmony_ci        self.tv.pack()
17827db96d56Sopenharmony_ci        self.tv.update()
17837db96d56Sopenharmony_ci
17847db96d56Sopenharmony_ci        pos_y = set()
17857db96d56Sopenharmony_ci        found = set()
17867db96d56Sopenharmony_ci        for i in range(0, 100, 10):
17877db96d56Sopenharmony_ci            if len(found) == 2: # item1 and item2 already found
17887db96d56Sopenharmony_ci                break
17897db96d56Sopenharmony_ci            item_id = self.tv.identify_row(i)
17907db96d56Sopenharmony_ci            if item_id and item_id not in found:
17917db96d56Sopenharmony_ci                pos_y.add(i)
17927db96d56Sopenharmony_ci                found.add(item_id)
17937db96d56Sopenharmony_ci
17947db96d56Sopenharmony_ci        self.assertEqual(len(pos_y), 2) # item1 and item2 y pos
17957db96d56Sopenharmony_ci        for y in pos_y:
17967db96d56Sopenharmony_ci            simulate_mouse_click(self.tv, 0, y)
17977db96d56Sopenharmony_ci
17987db96d56Sopenharmony_ci        # by now there should be 4 things in the events list, since each
17997db96d56Sopenharmony_ci        # item had a bind for two events that were simulated above
18007db96d56Sopenharmony_ci        self.assertEqual(len(events), 4)
18017db96d56Sopenharmony_ci        for evt in zip(events[::2], events[1::2]):
18027db96d56Sopenharmony_ci            self.assertEqual(evt, (1, 2))
18037db96d56Sopenharmony_ci
18047db96d56Sopenharmony_ci    def test_tag_configure(self):
18057db96d56Sopenharmony_ci        # Just testing parameter passing for now
18067db96d56Sopenharmony_ci        self.assertRaises(TypeError, self.tv.tag_configure)
18077db96d56Sopenharmony_ci        self.assertRaises(tkinter.TclError, self.tv.tag_configure,
18087db96d56Sopenharmony_ci            'test', sky='blue')
18097db96d56Sopenharmony_ci        self.tv.tag_configure('test', foreground='blue')
18107db96d56Sopenharmony_ci        self.assertEqual(str(self.tv.tag_configure('test', 'foreground')),
18117db96d56Sopenharmony_ci            'blue')
18127db96d56Sopenharmony_ci        self.assertEqual(str(self.tv.tag_configure('test', foreground=None)),
18137db96d56Sopenharmony_ci            'blue')
18147db96d56Sopenharmony_ci        self.assertIsInstance(self.tv.tag_configure('test'), dict)
18157db96d56Sopenharmony_ci
18167db96d56Sopenharmony_ci    def test_tag_has(self):
18177db96d56Sopenharmony_ci        item1 = self.tv.insert('', 'end', text='Item 1', tags=['tag1'])
18187db96d56Sopenharmony_ci        item2 = self.tv.insert('', 'end', text='Item 2', tags=['tag2'])
18197db96d56Sopenharmony_ci        self.assertRaises(TypeError, self.tv.tag_has)
18207db96d56Sopenharmony_ci        self.assertRaises(TclError, self.tv.tag_has, 'tag1', 'non-existing')
18217db96d56Sopenharmony_ci        self.assertTrue(self.tv.tag_has('tag1', item1))
18227db96d56Sopenharmony_ci        self.assertFalse(self.tv.tag_has('tag1', item2))
18237db96d56Sopenharmony_ci        self.assertFalse(self.tv.tag_has('tag2', item1))
18247db96d56Sopenharmony_ci        self.assertTrue(self.tv.tag_has('tag2', item2))
18257db96d56Sopenharmony_ci        self.assertFalse(self.tv.tag_has('tag3', item1))
18267db96d56Sopenharmony_ci        self.assertFalse(self.tv.tag_has('tag3', item2))
18277db96d56Sopenharmony_ci        self.assertEqual(self.tv.tag_has('tag1'), (item1,))
18287db96d56Sopenharmony_ci        self.assertEqual(self.tv.tag_has('tag2'), (item2,))
18297db96d56Sopenharmony_ci        self.assertEqual(self.tv.tag_has('tag3'), ())
18307db96d56Sopenharmony_ci
18317db96d56Sopenharmony_ci
18327db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
18337db96d56Sopenharmony_ciclass SeparatorTest(AbstractWidgetTest, unittest.TestCase):
18347db96d56Sopenharmony_ci    OPTIONS = (
18357db96d56Sopenharmony_ci        'class', 'cursor', 'orient', 'style', 'takefocus',
18367db96d56Sopenharmony_ci        # 'state'?
18377db96d56Sopenharmony_ci    )
18387db96d56Sopenharmony_ci    default_orient = 'horizontal'
18397db96d56Sopenharmony_ci
18407db96d56Sopenharmony_ci    def create(self, **kwargs):
18417db96d56Sopenharmony_ci        return ttk.Separator(self.root, **kwargs)
18427db96d56Sopenharmony_ci
18437db96d56Sopenharmony_ci
18447db96d56Sopenharmony_ci@add_standard_options(StandardTtkOptionsTests)
18457db96d56Sopenharmony_ciclass SizegripTest(AbstractWidgetTest, unittest.TestCase):
18467db96d56Sopenharmony_ci    OPTIONS = (
18477db96d56Sopenharmony_ci        'class', 'cursor', 'style', 'takefocus',
18487db96d56Sopenharmony_ci        # 'state'?
18497db96d56Sopenharmony_ci    )
18507db96d56Sopenharmony_ci
18517db96d56Sopenharmony_ci    def create(self, **kwargs):
18527db96d56Sopenharmony_ci        return ttk.Sizegrip(self.root, **kwargs)
18537db96d56Sopenharmony_ci
18547db96d56Sopenharmony_ci
18557db96d56Sopenharmony_ciclass DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
18567db96d56Sopenharmony_ci
18577db96d56Sopenharmony_ci    def test_frame(self):
18587db96d56Sopenharmony_ci        self._test_widget(ttk.Frame)
18597db96d56Sopenharmony_ci
18607db96d56Sopenharmony_ci    def test_label(self):
18617db96d56Sopenharmony_ci        self._test_widget(ttk.Label)
18627db96d56Sopenharmony_ci
18637db96d56Sopenharmony_ci
18647db96d56Sopenharmony_citests_gui = (
18657db96d56Sopenharmony_ci        ButtonTest, CheckbuttonTest, ComboboxTest, EntryTest,
18667db96d56Sopenharmony_ci        FrameTest, LabelFrameTest, LabelTest, MenubuttonTest,
18677db96d56Sopenharmony_ci        NotebookTest, PanedWindowTest, ProgressbarTest,
18687db96d56Sopenharmony_ci        RadiobuttonTest, ScaleTest, ScrollbarTest, SeparatorTest,
18697db96d56Sopenharmony_ci        SizegripTest, SpinboxTest, TreeviewTest, WidgetTest, DefaultRootTest,
18707db96d56Sopenharmony_ci        )
18717db96d56Sopenharmony_ci
18727db96d56Sopenharmony_ciif __name__ == "__main__":
18737db96d56Sopenharmony_ci    unittest.main()
1874