1import sys 2import unittest 3import Tkinter 4import ttk 5from test.test_support import requires, run_unittest 6 7import support 8 9requires('gui') 10 11class LabeledScaleTest(unittest.TestCase): 12 13 def setUp(self): 14 support.root_deiconify() 15 16 def tearDown(self): 17 support.root_withdraw() 18 19 20 def test_widget_destroy(self): 21 # automatically created variable 22 x = ttk.LabeledScale() 23 var = x._variable._name 24 x.destroy() 25 self.assertRaises(Tkinter.TclError, x.tk.globalgetvar, var) 26 27 # manually created variable 28 myvar = Tkinter.DoubleVar() 29 name = myvar._name 30 x = ttk.LabeledScale(variable=myvar) 31 x.destroy() 32 self.assertEqual(x.tk.globalgetvar(name), myvar.get()) 33 del myvar 34 self.assertRaises(Tkinter.TclError, x.tk.globalgetvar, name) 35 36 # checking that the tracing callback is properly removed 37 myvar = Tkinter.IntVar() 38 # LabeledScale will start tracing myvar 39 x = ttk.LabeledScale(variable=myvar) 40 x.destroy() 41 # Unless the tracing callback was removed, creating a new 42 # LabeledScale with the same var will cause an error now. This 43 # happens because the variable will be set to (possibly) a new 44 # value which causes the tracing callback to be called and then 45 # it tries calling instance attributes not yet defined. 46 ttk.LabeledScale(variable=myvar) 47 if hasattr(sys, 'last_type'): 48 self.assertFalse(sys.last_type == Tkinter.TclError) 49 50 51 def test_initialization(self): 52 # master passing 53 x = ttk.LabeledScale() 54 self.assertEqual(x.master, Tkinter._default_root) 55 x.destroy() 56 master = Tkinter.Frame() 57 x = ttk.LabeledScale(master) 58 self.assertEqual(x.master, master) 59 x.destroy() 60 61 # variable initialization/passing 62 passed_expected = ((2.5, 2), ('0', 0), (0, 0), (10, 10), 63 (-1, -1), (sys.maxint + 1, sys.maxint + 1)) 64 for pair in passed_expected: 65 x = ttk.LabeledScale(from_=pair[0]) 66 self.assertEqual(x.value, pair[1]) 67 x.destroy() 68 x = ttk.LabeledScale(from_='2.5') 69 self.assertRaises(ValueError, x._variable.get) 70 x.destroy() 71 x = ttk.LabeledScale(from_=None) 72 self.assertRaises(ValueError, x._variable.get) 73 x.destroy() 74 # variable should have its default value set to the from_ value 75 myvar = Tkinter.DoubleVar(value=20) 76 x = ttk.LabeledScale(variable=myvar) 77 self.assertEqual(x.value, 0) 78 x.destroy() 79 # check that it is really using a DoubleVar 80 x = ttk.LabeledScale(variable=myvar, from_=0.5) 81 self.assertEqual(x.value, 0.5) 82 self.assertEqual(x._variable._name, myvar._name) 83 x.destroy() 84 85 # widget positionment 86 def check_positions(scale, scale_pos, label, label_pos): 87 self.assertEqual(scale.pack_info()['side'], scale_pos) 88 self.assertEqual(label.place_info()['anchor'], label_pos) 89 x = ttk.LabeledScale(compound='top') 90 check_positions(x.scale, 'bottom', x.label, 'n') 91 x.destroy() 92 x = ttk.LabeledScale(compound='bottom') 93 check_positions(x.scale, 'top', x.label, 's') 94 x.destroy() 95 x = ttk.LabeledScale(compound='unknown') # invert default positions 96 check_positions(x.scale, 'top', x.label, 's') 97 x.destroy() 98 x = ttk.LabeledScale() # take default positions 99 check_positions(x.scale, 'bottom', x.label, 'n') 100 x.destroy() 101 102 # extra, and invalid, kwargs 103 self.assertRaises(Tkinter.TclError, ttk.LabeledScale, a='b') 104 105 106 def test_horizontal_range(self): 107 lscale = ttk.LabeledScale(from_=0, to=10) 108 lscale.pack() 109 lscale.wait_visibility() 110 lscale.update() 111 112 linfo_1 = lscale.label.place_info() 113 prev_xcoord = lscale.scale.coords()[0] 114 self.assertEqual(prev_xcoord, int(linfo_1['x'])) 115 # change range to: from -5 to 5. This should change the x coord of 116 # the scale widget, since 0 is at the middle of the new 117 # range. 118 lscale.scale.configure(from_=-5, to=5) 119 # The following update is needed since the test doesn't use mainloop, 120 # at the same time this shouldn't affect test outcome 121 lscale.update() 122 curr_xcoord = lscale.scale.coords()[0] 123 self.assertTrue(prev_xcoord != curr_xcoord) 124 # the label widget should have been repositioned too 125 linfo_2 = lscale.label.place_info() 126 self.assertEqual(lscale.label['text'], 0) 127 self.assertEqual(curr_xcoord, int(linfo_2['x'])) 128 # change the range back 129 lscale.scale.configure(from_=0, to=10) 130 self.assertTrue(prev_xcoord != curr_xcoord) 131 self.assertEqual(prev_xcoord, int(linfo_1['x'])) 132 133 lscale.destroy() 134 135 136 def test_variable_change(self): 137 x = ttk.LabeledScale() 138 x.pack() 139 x.wait_visibility() 140 x.update() 141 142 curr_xcoord = x.scale.coords()[0] 143 newval = x.value + 1 144 x.value = newval 145 # The following update is needed since the test doesn't use mainloop, 146 # at the same time this shouldn't affect test outcome 147 x.update() 148 self.assertEqual(x.label['text'], newval) 149 self.assertTrue(x.scale.coords()[0] > curr_xcoord) 150 self.assertEqual(x.scale.coords()[0], 151 int(x.label.place_info()['x'])) 152 153 # value outside range 154 x.value = x.scale['to'] + 1 # no changes shouldn't happen 155 x.update() 156 self.assertEqual(x.label['text'], newval) 157 self.assertEqual(x.scale.coords()[0], 158 int(x.label.place_info()['x'])) 159 160 x.destroy() 161 162 163 def test_resize(self): 164 x = ttk.LabeledScale() 165 x.pack(expand=True, fill='both') 166 x.wait_visibility() 167 x.update() 168 169 width, height = x.master.winfo_width(), x.master.winfo_height() 170 width_new, height_new = width * 2, height * 2 171 172 x.value = 3 173 x.update() 174 x.master.wm_geometry("%dx%d" % (width_new, height_new)) 175 self.assertEqual(int(x.label.place_info()['x']), 176 x.scale.coords()[0]) 177 178 # Reset geometry 179 x.master.wm_geometry("%dx%d" % (width, height)) 180 x.destroy() 181 182 183class OptionMenuTest(unittest.TestCase): 184 185 def setUp(self): 186 support.root_deiconify() 187 self.textvar = Tkinter.StringVar() 188 189 def tearDown(self): 190 del self.textvar 191 support.root_withdraw() 192 193 194 def test_widget_destroy(self): 195 var = Tkinter.StringVar() 196 optmenu = ttk.OptionMenu(None, var) 197 name = var._name 198 optmenu.update_idletasks() 199 optmenu.destroy() 200 self.assertEqual(optmenu.tk.globalgetvar(name), var.get()) 201 del var 202 self.assertRaises(Tkinter.TclError, optmenu.tk.globalgetvar, name) 203 204 205 def test_initialization(self): 206 self.assertRaises(Tkinter.TclError, 207 ttk.OptionMenu, None, self.textvar, invalid='thing') 208 209 optmenu = ttk.OptionMenu(None, self.textvar, 'b', 'a', 'b') 210 self.assertEqual(optmenu._variable.get(), 'b') 211 212 self.assertTrue(optmenu['menu']) 213 self.assertTrue(optmenu['textvariable']) 214 215 optmenu.destroy() 216 217 218 def test_menu(self): 219 items = ('a', 'b', 'c') 220 default = 'a' 221 optmenu = ttk.OptionMenu(None, self.textvar, default, *items) 222 found_default = False 223 for i in range(len(items)): 224 value = optmenu['menu'].entrycget(i, 'value') 225 self.assertEqual(value, items[i]) 226 if value == default: 227 found_default = True 228 self.assertTrue(found_default) 229 optmenu.destroy() 230 231 # default shouldn't be in menu if it is not part of values 232 default = 'd' 233 optmenu = ttk.OptionMenu(None, self.textvar, default, *items) 234 curr = None 235 i = 0 236 while True: 237 last, curr = curr, optmenu['menu'].entryconfigure(i, 'value') 238 if last == curr: 239 # no more menu entries 240 break 241 self.assertFalse(curr == default) 242 i += 1 243 self.assertEqual(i, len(items)) 244 245 # check that variable is updated correctly 246 optmenu.pack() 247 optmenu.wait_visibility() 248 optmenu['menu'].invoke(0) 249 self.assertEqual(optmenu._variable.get(), items[0]) 250 251 # changing to an invalid index shouldn't change the variable 252 self.assertRaises(Tkinter.TclError, optmenu['menu'].invoke, -1) 253 self.assertEqual(optmenu._variable.get(), items[0]) 254 255 optmenu.destroy() 256 257 # specifying a callback 258 success = [] 259 def cb_test(item): 260 self.assertEqual(item, items[1]) 261 success.append(True) 262 optmenu = ttk.OptionMenu(None, self.textvar, 'a', command=cb_test, 263 *items) 264 optmenu['menu'].invoke(1) 265 if not success: 266 self.fail("Menu callback not invoked") 267 268 optmenu.destroy() 269 270 271tests_gui = (LabeledScaleTest, OptionMenuTest) 272 273if __name__ == "__main__": 274 run_unittest(*tests_gui) 275