blob: 66a5c6db23c556f0bd54d3db5617df5c095d3d78 [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
8import io
9from contextlib import contextmanager
10
11NotDefined = object()
12
13# A dispatch table all 8 combinations of providing
14# sep, end, and file
15# I use this machinery so that I'm not just passing default
16# values to print, I'm eiher passing or not passing in the
17# arguments
18dispatch = {
19 (False, False, False):
20 lambda args, sep, end, file: print(*args),
21 (False, False, True):
22 lambda args, sep, end, file: print(file=file, *args),
23 (False, True, False):
24 lambda args, sep, end, file: print(end=end, *args),
25 (False, True, True):
26 lambda args, sep, end, file: print(end=end, file=file, *args),
27 (True, False, False):
28 lambda args, sep, end, file: print(sep=sep, *args),
29 (True, False, True):
30 lambda args, sep, end, file: print(sep=sep, file=file, *args),
31 (True, True, False):
32 lambda args, sep, end, file: print(sep=sep, end=end, *args),
33 (True, True, True):
34 lambda args, sep, end, file: print(sep=sep, end=end, file=file, *args),
35 }
36
37@contextmanager
38def stdout_redirected(new_stdout):
39 save_stdout = sys.stdout
40 sys.stdout = new_stdout
41 try:
42 yield None
43 finally:
44 sys.stdout = save_stdout
45
46# Class used to test __str__ and print
47class ClassWith__str__:
48 def __init__(self, x):
49 self.x = x
50 def __str__(self):
51 return self.x
52
53class TestPrint(unittest.TestCase):
54 def check(self, expected, args, *,
55 sep=NotDefined, end=NotDefined, file=NotDefined):
56 # Capture sys.stdout in a StringIO. Call print with args,
57 # and with sep, end, and file, if they're defined. Result
58 # must match expected.
59
60 # Look up the actual function to call, based on if sep, end, and file
61 # are defined
62 fn = dispatch[(sep is not NotDefined,
63 end is not NotDefined,
64 file is not NotDefined)]
65
66 t = io.StringIO()
67 with stdout_redirected(t):
68 fn(args, sep, end, file)
69
70 self.assertEqual(t.getvalue(), expected)
71
72 def test_print(self):
73 def x(expected, args, *, sep=NotDefined, end=NotDefined):
74 # Run the test 2 ways: not using file, and using
75 # file directed to a StringIO
76
77 self.check(expected, args, sep=sep, end=end)
78
79 # When writing to a file, stdout is expected to be empty
80 o = io.StringIO()
81 self.check('', args, sep=sep, end=end, file=o)
82
83 # And o will contain the expected output
84 self.assertEqual(o.getvalue(), expected)
85
86 x('\n', ())
87 x('a\n', ('a',))
88 x('None\n', (None,))
89 x('1 2\n', (1, 2))
90 x('1*2\n', (1, 2), sep='*')
91 x('1 s', (1, 's'), end='')
92 x('a\nb\n', ('a', 'b'), sep='\n')
93 x('1.01', (1.0, 1), sep='', end='')
94 x('1*a*1.3+', (1, 'a', 1.3), sep='*', end='+')
95
96 x('*\n', (ClassWith__str__('*'),))
97
98def test_main():
99 test_support.run_unittest(TestPrint)
100
101if __name__ == "__main__":
102 test_main()