@@ -1542,6 +1542,185 @@ def test_entryconfigure_variable(self):
15421542 m1 .entryconfigure (1 , variable = v2 )
15431543 self .assertEqual (str (m1 .entrycget (1 , 'variable' )), str (v2 ))
15441544
1545+ def test_add (self ):
1546+ m = self .create (tearoff = False )
1547+ m .add_command (label = 'Command' )
1548+ m .add_checkbutton (label = 'Checkbutton' )
1549+ m .add_radiobutton (label = 'Radiobutton' )
1550+ m .add_separator ()
1551+ m .add_cascade (label = 'Cascade' , menu = tkinter .Menu (m , tearoff = False ))
1552+ self .assertEqual (m .index ('end' ), 4 )
1553+ self .assertEqual ([m .type (i ) for i in range (5 )],
1554+ ['command' , 'checkbutton' , 'radiobutton' ,
1555+ 'separator' , 'cascade' ])
1556+ self .assertEqual (m .entrycget (0 , 'label' ), 'Command' )
1557+ self .assertRaisesRegex (TclError , 'bad menu entry type "spam"' ,
1558+ m .add , 'spam' )
1559+
1560+ def test_insert (self ):
1561+ m = self .create (tearoff = False )
1562+ m .add_command (label = 'A' )
1563+ m .add_command (label = 'C' )
1564+ m .insert_command (1 , label = 'B' )
1565+ m .insert_separator (0 )
1566+ m .insert_checkbutton ('end' , label = 'D' )
1567+ m .insert_radiobutton (0 , label = 'top' )
1568+ m .insert_cascade (2 , label = 'sub' ,
1569+ menu = tkinter .Menu (m , tearoff = False ))
1570+ self .assertEqual (
1571+ [m .type (i ) for i in range (m .index ('end' ) + 1 )],
1572+ ['radiobutton' , 'separator' , 'cascade' , 'command' ,
1573+ 'command' , 'command' , 'checkbutton' ])
1574+ self .assertEqual (
1575+ [m .entrycget (i , 'label' ) for i in (3 , 4 , 5 )],
1576+ ['A' , 'B' , 'C' ])
1577+ self .assertRaisesRegex (TclError , 'bad menu entry type "spam"' ,
1578+ m .insert , 0 , 'spam' )
1579+ self .assertRaisesRegex (TclError , 'bad menu entry index "spam"' ,
1580+ m .insert_command , 'spam' , label = 'z' )
1581+
1582+ def test_delete (self ):
1583+ m = self .create (tearoff = False )
1584+ commands = []
1585+ for label in 'ABCDE' :
1586+ m .add_command (label = label ,
1587+ command = lambda label = label : commands .append (label ))
1588+ # The Tcl command for a deleted item is cleaned up.
1589+ funcid = str (m .entrycget (2 , 'command' ))
1590+ self .assertEqual (
1591+ m .tk .splitlist (m .tk .call ('info' , 'commands' , funcid )), (funcid ,))
1592+
1593+ m .delete (2 ) # Delete a single item ('C').
1594+ self .assertEqual ([m .entrycget (i , 'label' ) for i in range (4 )],
1595+ ['A' , 'B' , 'D' , 'E' ])
1596+ self .assertEqual (
1597+ m .tk .splitlist (m .tk .call ('info' , 'commands' , funcid )), ())
1598+
1599+ m .delete (1 , 2 ) # Delete a range ('B' and 'D').
1600+ self .assertEqual ([m .entrycget (i , 'label' ) for i in range (2 )],
1601+ ['A' , 'E' ])
1602+ self .assertRaises (TypeError , m .delete )
1603+
1604+ def test_index (self ):
1605+ m = self .create (tearoff = False )
1606+ self .assertIsNone (m .index ('end' ))
1607+ m .add_command (label = 'First' )
1608+ m .add_command (label = 'Second' )
1609+ self .assertEqual (m .index ('end' ), 1 )
1610+ self .assertEqual (m .index ('last' ), 1 )
1611+ self .assertEqual (m .index ('Second' ), 1 )
1612+ self .assertEqual (m .index (0 ), 0 )
1613+ # 'active' and 'none' map to None when no item is active.
1614+ self .assertIsNone (m .index ('active' ))
1615+ self .assertIsNone (m .index ('none' ))
1616+ self .assertRaisesRegex (TclError , 'bad menu entry index "spam"' ,
1617+ m .index , 'spam' )
1618+
1619+ def test_invoke (self ):
1620+ m = self .create (tearoff = False )
1621+ commands = []
1622+ m .add_command (label = 'Command' ,
1623+ command = lambda : commands .append ('invoked' ))
1624+ var = tkinter .IntVar (self .root )
1625+ m .add_checkbutton (label = 'Check' , variable = var ,
1626+ onvalue = 1 , offvalue = 0 )
1627+ rvar = tkinter .StringVar (self .root )
1628+ m .add_radiobutton (label = 'Radio' , variable = rvar , value = 'on' )
1629+
1630+ m .invoke (0 )
1631+ self .assertEqual (commands , ['invoked' ])
1632+ m .invoke (1 )
1633+ self .assertEqual (var .get (), 1 )
1634+ m .invoke (1 )
1635+ self .assertEqual (var .get (), 0 )
1636+ m .invoke (2 )
1637+ self .assertEqual (rvar .get (), 'on' )
1638+ self .assertRaisesRegex (TclError , 'bad menu entry index "spam"' ,
1639+ m .invoke , 'spam' )
1640+
1641+ def test_xposition_yposition (self ):
1642+ m = self .create (tearoff = False )
1643+ m .add_command (label = 'First' )
1644+ m .add_command (label = 'Second' )
1645+ m .update_idletasks ()
1646+ self .assertIsInstance (m .xposition (0 ), int )
1647+ y0 = m .yposition (0 )
1648+ y1 = m .yposition (1 )
1649+ self .assertIsInstance (y0 , int )
1650+ self .assertLess (y0 , y1 )
1651+ # An out-of-range index gives the position past the last item.
1652+ self .assertEqual (m .xposition ('end' ), m .xposition (1 ))
1653+ self .assertRaisesRegex (TclError , 'bad menu entry index "spam"' ,
1654+ m .xposition , 'spam' )
1655+ self .assertRaisesRegex (TclError , 'bad menu entry index "spam"' ,
1656+ m .yposition , 'spam' )
1657+
1658+ def test_post_unpost (self ):
1659+ m = self .create (tearoff = False )
1660+ m .add_command (label = 'First' )
1661+ m .add_command (label = 'Second' )
1662+ self .assertFalse (m .winfo_ismapped ())
1663+
1664+ m .post (0 , 0 )
1665+ m .update ()
1666+ self .assertTrue (m .winfo_ismapped ())
1667+ m .unpost ()
1668+ m .update ()
1669+ self .assertFalse (m .winfo_ismapped ())
1670+
1671+ m .tk_popup (0 , 0 )
1672+ m .update ()
1673+ self .assertTrue (m .winfo_ismapped ())
1674+ m .unpost ()
1675+ m .update ()
1676+ self .assertFalse (m .winfo_ismapped ())
1677+
1678+ def check_entry_option (self , m , index , option , value , expected = None ):
1679+ if expected is None :
1680+ expected = value
1681+ m .entryconfigure (index , ** {option : value })
1682+ self .assertEqual (str (m .entrycget (index , option )), str (expected ))
1683+ self .assertEqual (str (m .entryconfigure (index , option )[4 ]), str (expected ))
1684+
1685+ def test_entry_options (self ):
1686+ m = self .create (tearoff = False )
1687+ m .add_command (label = 'Command' )
1688+ self .check_entry_option (m , 0 , 'accelerator' , 'Ctrl+O' )
1689+ self .check_entry_option (m , 0 , 'underline' , 2 )
1690+ self .check_entry_option (m , 0 , 'state' , 'disabled' )
1691+ self .check_entry_option (m , 0 , 'background' , 'red' )
1692+ self .check_entry_option (m , 0 , 'foreground' , 'blue' )
1693+ self .check_entry_option (m , 0 , 'columnbreak' , 1 )
1694+ self .check_entry_option (m , 0 , 'hidemargin' , 1 )
1695+
1696+ m .add_checkbutton (label = 'Checkbutton' )
1697+ self .check_entry_option (m , 1 , 'onvalue' , 'Y' )
1698+ self .check_entry_option (m , 1 , 'offvalue' , 'N' )
1699+ self .check_entry_option (m , 1 , 'indicatoron' , 0 )
1700+
1701+ m .add_radiobutton (label = 'Radiobutton' )
1702+ self .check_entry_option (m , 2 , 'value' , 'V' )
1703+ self .check_entry_option (m , 2 , 'selectcolor' , 'green' )
1704+
1705+ def test_entry_options_invalid (self ):
1706+ m = self .create (tearoff = False )
1707+ m .add_command (label = 'Command' )
1708+ self .assertRaisesRegex (TclError , 'unknown option "-spam"' ,
1709+ m .entrycget , 0 , 'spam' )
1710+ self .assertRaisesRegex (TclError , 'unknown option "-spam"' ,
1711+ m .entryconfigure , 0 , spam = 'x' )
1712+ self .assertRaisesRegex (TclError , 'bad state "spam"' ,
1713+ m .entryconfigure , 0 , state = 'spam' )
1714+ self .assertRaisesRegex (TclError , 'expected integer but got "spam"' ,
1715+ m .entryconfigure , 0 , underline = 'spam' )
1716+ self .assertRaisesRegex (TclError , 'unknown color name "spam"' ,
1717+ m .entryconfigure , 0 , background = 'spam' )
1718+ self .assertRaisesRegex (TclError , 'expected boolean value but got "spam"' ,
1719+ m .entryconfigure , 0 , columnbreak = 'spam' )
1720+ # onvalue applies only to checkbutton and radiobutton entries.
1721+ self .assertRaisesRegex (TclError , 'unknown option "-onvalue"' ,
1722+ m .entrycget , 0 , 'onvalue' )
1723+
15451724
15461725@add_configure_tests (PixelSizeTests , StandardOptionsTests )
15471726class MessageTest (AbstractWidgetTest , unittest .TestCase ):
0 commit comments