blob: baeab3da49c7ac192ba08606501d66f29497306c [file] [log] [blame]
Eric Smith799c3002008-03-18 15:35:27 +00001"""Test correct operation of the print function.
2"""
3
4import unittest
5from test import test_support
6
7import sys
Eric Smith01a3e2b2008-03-18 23:48:28 +00008try:
9 # 3.x
10 from io import StringIO
11except ImportError:
12 # 2.x
13 from StringIO import StringIO
14
Eric Smith799c3002008-03-18 15:35:27 +000015from contextlib import contextmanager
16
17NotDefined = object()
18
19# A dispatch table all 8 combinations of providing
20# sep, end, and file
21# I use this machinery so that I'm not just passing default
22# values to print, I'm eiher passing or not passing in the
23# arguments
24dispatch = {
25 (False, False, False):
26 lambda args, sep, end, file: print(*args),
27 (False, False, True):
28 lambda args, sep, end, file: print(file=file, *args),
29 (False, True, False):
30 lambda args, sep, end, file: print(end=end, *args),
31 (False, True, True):
32 lambda args, sep, end, file: print(end=end, file=file, *args),
33 (True, False, False):
34 lambda args, sep, end, file: print(sep=sep, *args),
35 (True, False, True):
36 lambda args, sep, end, file: print(sep=sep, file=file, *args),
37 (True, True, False):
38 lambda args, sep, end, file: print(sep=sep, end=end, *args),
39 (True, True, True):
40 lambda args, sep, end, file: print(sep=sep, end=end, file=file, *args),
41 }
42
43@contextmanager
44def stdout_redirected(new_stdout):
45 save_stdout = sys.stdout
46 sys.stdout = new_stdout
47 try:
48 yield None
49 finally:
50 sys.stdout = save_stdout
51
52# Class used to test __str__ and print
53class ClassWith__str__:
54 def __init__(self, x):
55 self.x = x
56 def __str__(self):
57 return self.x
58
59class TestPrint(unittest.TestCase):
Eric Smith01a3e2b2008-03-18 23:48:28 +000060 def check(self, expected, args,
Eric Smith799c3002008-03-18 15:35:27 +000061 sep=NotDefined, end=NotDefined, file=NotDefined):
62 # Capture sys.stdout in a StringIO. Call print with args,
63 # and with sep, end, and file, if they're defined. Result
64 # must match expected.
65
66 # Look up the actual function to call, based on if sep, end, and file
67 # are defined
68 fn = dispatch[(sep is not NotDefined,
69 end is not NotDefined,
70 file is not NotDefined)]
71
Eric Smith01a3e2b2008-03-18 23:48:28 +000072 t = StringIO()
Eric Smith799c3002008-03-18 15:35:27 +000073 with stdout_redirected(t):
74 fn(args, sep, end, file)
75
76 self.assertEqual(t.getvalue(), expected)
77
78 def test_print(self):
Eric Smith01a3e2b2008-03-18 23:48:28 +000079 def x(expected, args, sep=NotDefined, end=NotDefined):
Eric Smith799c3002008-03-18 15:35:27 +000080 # Run the test 2 ways: not using file, and using
81 # file directed to a StringIO
82
83 self.check(expected, args, sep=sep, end=end)
84
85 # When writing to a file, stdout is expected to be empty
Eric Smith01a3e2b2008-03-18 23:48:28 +000086 o = StringIO()
Eric Smith799c3002008-03-18 15:35:27 +000087 self.check('', args, sep=sep, end=end, file=o)
88
89 # And o will contain the expected output
90 self.assertEqual(o.getvalue(), expected)
91
92 x('\n', ())
93 x('a\n', ('a',))
94 x('None\n', (None,))
95 x('1 2\n', (1, 2))
Eric Smith01a3e2b2008-03-18 23:48:28 +000096 x('1 2\n', (1, ' ', 2))
Eric Smith799c3002008-03-18 15:35:27 +000097 x('1*2\n', (1, 2), sep='*')
98 x('1 s', (1, 's'), end='')
99 x('a\nb\n', ('a', 'b'), sep='\n')
100 x('1.01', (1.0, 1), sep='', end='')
101 x('1*a*1.3+', (1, 'a', 1.3), sep='*', end='+')
Eric Smith01a3e2b2008-03-18 23:48:28 +0000102 x('a\n\nb\n', ('a\n', 'b'), sep='\n')
103 x('\0+ +\0\n', ('\0', ' ', '\0'), sep='+')
104
105 x('a\n b\n', ('a\n', 'b'))
106 x('a\n b\n', ('a\n', 'b'), sep=None)
107 x('a\n b\n', ('a\n', 'b'), end=None)
108 x('a\n b\n', ('a\n', 'b'), sep=None, end=None)
Eric Smith799c3002008-03-18 15:35:27 +0000109
110 x('*\n', (ClassWith__str__('*'),))
Eric Smith01a3e2b2008-03-18 23:48:28 +0000111 x('abc 1\n', (ClassWith__str__('abc'), 1))
112
113 # errors
114 self.assertRaises(TypeError, print, '', sep=3)
115 self.assertRaises(TypeError, print, '', end=3)
116 self.assertRaises(AttributeError, print, '', file='')
Eric Smith799c3002008-03-18 15:35:27 +0000117
118def test_main():
119 test_support.run_unittest(TestPrint)
120
121if __name__ == "__main__":
122 test_main()