blob: bc15680f76860126f7274d18d76d157d79fdc722 [file] [log] [blame]
David Aschere2b4b322004-02-18 05:59:53 +00001import unittest
Serhiy Storchaka4a880412013-02-07 15:37:53 +02002import sys
David Aschere2b4b322004-02-18 05:59:53 +00003import os
Serhiy Storchaka42035702013-08-21 21:46:12 +03004import _testcapi
Neal Norwitz63dfece2004-02-19 02:37:29 +00005from test import test_support
Ezio Melotti794e5572013-05-07 09:34:49 +03006from subprocess import Popen, PIPE
R. David Murray597ebab2009-03-31 18:32:17 +00007
8# Skip this test if the _tkinter module wasn't built.
9_tkinter = test_support.import_module('_tkinter')
10
Guilherme Polo8e5e4382009-02-07 02:20:29 +000011from Tkinter import Tcl
David Aschere2b4b322004-02-18 05:59:53 +000012from _tkinter import TclError
13
Serhiy Storchaka94025332013-09-08 20:32:56 +030014tcl_version = _tkinter.TCL_VERSION.split('.')
15try:
16 for i in range(len(tcl_version)):
17 tcl_version[i] = int(tcl_version[i])
18except ValueError:
19 pass
20tcl_version = tuple(tcl_version)
21
Serhiy Storchaka15b67d72014-02-02 23:04:06 +020022_tk_patchlevel = None
23def get_tk_patchlevel():
24 global _tk_patchlevel
25 if _tk_patchlevel is None:
26 tcl = Tcl()
27 patchlevel = []
28 for x in tcl.call('info', 'patchlevel').split('.'):
29 try:
30 x = int(x, 10)
31 except ValueError:
32 x = -1
33 patchlevel.append(x)
34 _tk_patchlevel = tuple(patchlevel)
35 return _tk_patchlevel
36
Benjamin Petersonb3619be2009-01-30 02:24:39 +000037
38class TkinterTest(unittest.TestCase):
39
40 def testFlattenLen(self):
41 # flatten(<object with no length>)
42 self.assertRaises(TypeError, _tkinter._flatten, True)
43
44
David Aschere2b4b322004-02-18 05:59:53 +000045class TclTest(unittest.TestCase):
46
47 def setUp(self):
48 self.interp = Tcl()
Serhiy Storchaka5542b152013-12-25 17:28:50 +020049 self.wantobjects = self.interp.tk.wantobjects()
David Aschere2b4b322004-02-18 05:59:53 +000050
51 def testEval(self):
52 tcl = self.interp
53 tcl.eval('set a 1')
54 self.assertEqual(tcl.eval('set a'),'1')
55
56 def testEvalException(self):
57 tcl = self.interp
58 self.assertRaises(TclError,tcl.eval,'set a')
59
60 def testEvalException2(self):
61 tcl = self.interp
62 self.assertRaises(TclError,tcl.eval,'this is wrong')
63
64 def testCall(self):
65 tcl = self.interp
66 tcl.call('set','a','1')
67 self.assertEqual(tcl.call('set','a'),'1')
68
69 def testCallException(self):
70 tcl = self.interp
71 self.assertRaises(TclError,tcl.call,'set','a')
72
73 def testCallException2(self):
74 tcl = self.interp
75 self.assertRaises(TclError,tcl.call,'this','is','wrong')
76
77 def testSetVar(self):
78 tcl = self.interp
79 tcl.setvar('a','1')
80 self.assertEqual(tcl.eval('set a'),'1')
81
82 def testSetVarArray(self):
83 tcl = self.interp
84 tcl.setvar('a(1)','1')
85 self.assertEqual(tcl.eval('set a(1)'),'1')
86
87 def testGetVar(self):
88 tcl = self.interp
89 tcl.eval('set a 1')
90 self.assertEqual(tcl.getvar('a'),'1')
91
92 def testGetVarArray(self):
93 tcl = self.interp
94 tcl.eval('set a(1) 1')
95 self.assertEqual(tcl.getvar('a(1)'),'1')
96
97 def testGetVarException(self):
98 tcl = self.interp
99 self.assertRaises(TclError,tcl.getvar,'a')
100
101 def testGetVarArrayException(self):
102 tcl = self.interp
103 self.assertRaises(TclError,tcl.getvar,'a(1)')
104
105 def testUnsetVar(self):
106 tcl = self.interp
107 tcl.setvar('a',1)
108 self.assertEqual(tcl.eval('info exists a'),'1')
109 tcl.unsetvar('a')
110 self.assertEqual(tcl.eval('info exists a'),'0')
111
112 def testUnsetVarArray(self):
113 tcl = self.interp
114 tcl.setvar('a(1)',1)
115 tcl.setvar('a(2)',2)
116 self.assertEqual(tcl.eval('info exists a(1)'),'1')
117 self.assertEqual(tcl.eval('info exists a(2)'),'1')
118 tcl.unsetvar('a(1)')
119 self.assertEqual(tcl.eval('info exists a(1)'),'0')
120 self.assertEqual(tcl.eval('info exists a(2)'),'1')
121
122 def testUnsetVarException(self):
123 tcl = self.interp
124 self.assertRaises(TclError,tcl.unsetvar,'a')
Tim Peters27f88362004-07-08 04:22:35 +0000125
David Aschere2b4b322004-02-18 05:59:53 +0000126 def testEvalFile(self):
127 tcl = self.interp
128 filename = "testEvalFile.tcl"
129 fd = open(filename,'w')
130 script = """set a 1
131 set b 2
132 set c [ expr $a + $b ]
133 """
134 fd.write(script)
135 fd.close()
136 tcl.evalfile(filename)
Neal Norwitz9a8d55e2004-02-29 15:37:50 +0000137 os.remove(filename)
David Aschere2b4b322004-02-18 05:59:53 +0000138 self.assertEqual(tcl.eval('set a'),'1')
139 self.assertEqual(tcl.eval('set b'),'2')
140 self.assertEqual(tcl.eval('set c'),'3')
141
142 def testEvalFileException(self):
143 tcl = self.interp
144 filename = "doesnotexists"
145 try:
146 os.remove(filename)
147 except Exception,e:
148 pass
149 self.assertRaises(TclError,tcl.evalfile,filename)
150
David Aschere2b4b322004-02-18 05:59:53 +0000151 def testPackageRequireException(self):
152 tcl = self.interp
153 self.assertRaises(TclError,tcl.eval,'package require DNE')
154
Zachary Ware57d35c62013-11-03 22:51:25 -0600155 @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows")
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000156 def testLoadWithUNC(self):
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000157 # Build a UNC path from the regular path.
158 # Something like
159 # \\%COMPUTERNAME%\c$\python27\python.exe
160
161 fullname = os.path.abspath(sys.executable)
162 if fullname[1] != ':':
Zachary Ware57d35c62013-11-03 22:51:25 -0600163 self.skipTest('unusable path: %r' % fullname)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000164 unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
165 fullname[0],
166 fullname[3:])
167
168 with test_support.EnvironmentVarGuard() as env:
169 env.unset("TCL_LIBRARY")
Ezio Melotti794e5572013-05-07 09:34:49 +0300170 cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000171
Zachary Ware57d35c62013-11-03 22:51:25 -0600172 try:
173 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
174 except WindowsError as e:
175 if e.winerror == 5:
176 self.skipTest('Not permitted to start the child process')
177 else:
178 raise
179
Ezio Melotti794e5572013-05-07 09:34:49 +0300180 out_data, err_data = p.communicate()
181
182 msg = '\n\n'.join(['"Tkinter.py" not in output',
183 'Command:', cmd,
184 'stdout:', out_data,
185 'stderr:', err_data])
186
187 self.assertIn('Tkinter.py', out_data, msg)
188
189 self.assertEqual(p.wait(), 0, 'Non-zero exit code')
190
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000191
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200192 def test_passing_values(self):
193 def passValue(value):
194 return self.interp.call('set', '_', value)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200195
196 self.assertEqual(passValue(True), True if self.wantobjects else '1')
197 self.assertEqual(passValue(False), False if self.wantobjects else '0')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200198 self.assertEqual(passValue(u'string'), u'string')
199 self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
200 for i in (0, 1, -1, int(2**31-1), int(-2**31)):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200201 self.assertEqual(passValue(i), i if self.wantobjects else str(i))
Ezio Melotti0a4a7e12013-02-23 08:19:00 +0200202 for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200203 sys.float_info.min, sys.float_info.max,
204 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200205 if self.wantobjects:
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200206 self.assertEqual(passValue(f), f)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200207 else:
208 self.assertEqual(float(passValue(f)), f)
209 if self.wantobjects:
210 f = passValue(float('nan'))
211 self.assertNotEqual(f, f)
212 self.assertEqual(passValue(float('inf')), float('inf'))
213 self.assertEqual(passValue(-float('inf')), -float('inf'))
214 else:
215 f = float(passValue(float('nan')))
216 self.assertNotEqual(f, f)
217 self.assertEqual(float(passValue(float('inf'))), float('inf'))
218 self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
219 self.assertEqual(passValue((1, '2', (3.4,))),
220 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000221
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200222 def test_user_command(self):
223 result = []
224 def testfunc(arg):
225 result.append(arg)
226 return arg
227 self.interp.createcommand('testfunc', testfunc)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200228 def check(value, expected, eq=self.assertEqual):
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200229 del result[:]
Serhiy Storchaka83515ec2014-01-23 11:03:02 +0200230 r = self.interp.call('testfunc', value)
231 self.assertEqual(len(result), 1)
232 self.assertIsInstance(result[0], str)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200233 eq(result[0], expected)
Serhiy Storchaka83515ec2014-01-23 11:03:02 +0200234 self.assertIsInstance(r, str)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200235 eq(r, expected)
236 def float_eq(actual, expected):
Serhiy Storchakaeb7ef942014-01-23 16:08:35 +0200237 expected = float(expected)
238 self.assertAlmostEqual(float(actual), expected,
239 delta=abs(expected) * 1e-10)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200240 def nan_eq(actual, expected):
241 actual = float(actual)
242 self.assertNotEqual(actual, actual)
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200243
244 check(True, '1')
245 check(False, '0')
246 check('string', 'string')
247 check('string\xbd', 'string\xbd')
248 check('string\u20ac', 'string\u20ac')
249 for i in (0, 1, -1, 2**31-1, -2**31):
250 check(i, str(i))
Serhiy Storchakadc976672014-01-23 14:38:44 +0200251 for f in (0.0, 1.0, -1.0):
252 check(f, repr(f))
253 for f in (1/3.0, sys.float_info.min, sys.float_info.max,
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200254 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakadc976672014-01-23 14:38:44 +0200255 check(f, f, eq=float_eq)
256 check(float('inf'), 'Inf', eq=float_eq)
257 check(-float('inf'), '-Inf', eq=float_eq)
258 check(float('nan'), 'NaN', eq=nan_eq)
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200259 check((), '')
260 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
261
Serhiy Storchakafab65422013-07-11 20:32:48 +0300262 def test_splitlist(self):
263 splitlist = self.interp.tk.splitlist
264 call = self.interp.tk.call
265 self.assertRaises(TypeError, splitlist)
266 self.assertRaises(TypeError, splitlist, 'a', 'b')
267 self.assertRaises(TypeError, splitlist, 2)
268 testcases = [
269 ('2', ('2',)),
270 ('', ()),
271 ('{}', ('',)),
272 ('""', ('',)),
273 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
274 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
275 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
276 (u'a \u20ac', ('a', '\xe2\x82\xac')),
277 ('a {b c}', ('a', 'b c')),
278 (r'a b\ c', ('a', 'b c')),
279 (('a', 'b c'), ('a', 'b c')),
280 ('a 2', ('a', '2')),
281 (('a', 2), ('a', 2)),
282 ('a 3.4', ('a', '3.4')),
283 (('a', 3.4), ('a', 3.4)),
284 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200285 (call('list', 1, '2', (3.4,)),
286 (1, '2', (3.4,)) if self.wantobjects else
287 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300288 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300289 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200290 if not self.wantobjects:
291 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
292 elif get_tk_patchlevel() < (8, 5, 5):
293 # Before 8.5.5 dicts were converted to lists through string
294 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
295 else:
296 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300297 testcases += [
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200298 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
299 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300300 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300301 for arg, res in testcases:
302 self.assertEqual(splitlist(arg), res)
303 self.assertRaises(TclError, splitlist, '{')
304
305 def test_split(self):
306 split = self.interp.tk.split
307 call = self.interp.tk.call
308 self.assertRaises(TypeError, split)
309 self.assertRaises(TypeError, split, 'a', 'b')
310 self.assertRaises(TypeError, split, 2)
311 testcases = [
312 ('2', '2'),
313 ('', ''),
314 ('{}', ''),
315 ('""', ''),
316 ('{', '{'),
317 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
318 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
319 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
320 (u'a \u20ac', ('a', '\xe2\x82\xac')),
321 ('a {b c}', ('a', ('b', 'c'))),
322 (r'a b\ c', ('a', ('b', 'c'))),
323 (('a', 'b c'), ('a', ('b', 'c'))),
324 (('a', u'b c'), ('a', ('b', 'c'))),
325 ('a 2', ('a', '2')),
326 (('a', 2), ('a', 2)),
327 ('a 3.4', ('a', '3.4')),
328 (('a', 3.4), ('a', 3.4)),
329 (('a', (2, 3.4)), ('a', (2, 3.4))),
330 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200331 (call('list', 1, '2', (3.4,)),
332 (1, '2', (3.4,)) if self.wantobjects else
333 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300334 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300335 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200336 if not self.wantobjects:
337 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
338 elif get_tk_patchlevel() < (8, 5, 5):
339 # Before 8.5.5 dicts were converted to lists through string
340 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
341 else:
342 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300343 testcases += [
344 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200345 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300346 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300347 for arg, res in testcases:
348 self.assertEqual(split(arg), res)
349
Neal Norwitz63dfece2004-02-19 02:37:29 +0000350
Serhiy Storchaka42035702013-08-21 21:46:12 +0300351class BigmemTclTest(unittest.TestCase):
352
353 def setUp(self):
354 self.interp = Tcl()
355
356 @unittest.skipUnless(_testcapi.INT_MAX < _testcapi.PY_SSIZE_T_MAX,
357 "needs UINT_MAX < SIZE_MAX")
358 @test_support.precisionbigmemtest(size=_testcapi.INT_MAX + 1, memuse=5,
359 dry_run=False)
360 def test_huge_string(self, size):
361 value = ' ' * size
362 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
363
364
Serhiy Storchaka78ecaba2013-11-20 17:44:38 +0200365def setUpModule():
366 if test_support.verbose:
367 tcl = Tcl()
368 print 'patchlevel =', tcl.call('info', 'patchlevel')
369
370
Neal Norwitz63dfece2004-02-19 02:37:29 +0000371def test_main():
Serhiy Storchaka42035702013-08-21 21:46:12 +0300372 test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
Neal Norwitz63dfece2004-02-19 02:37:29 +0000373
David Aschere2b4b322004-02-18 05:59:53 +0000374if __name__ == "__main__":
Neal Norwitz63dfece2004-02-19 02:37:29 +0000375 test_main()