Imported Upstream version 1.10.1
[platform/upstream/ninja.git] / misc / output_test.py
1 #!/usr/bin/env python3
2
3 """Runs ./ninja and checks if the output is correct.
4
5 In order to simulate a smart terminal it uses the 'script' command.
6 """
7
8 import os
9 import platform
10 import subprocess
11 import sys
12 import tempfile
13 import unittest
14
15 default_env = dict(os.environ)
16 if 'NINJA_STATUS' in default_env:
17     del default_env['NINJA_STATUS']
18 if 'CLICOLOR_FORCE' in default_env:
19     del default_env['CLICOLOR_FORCE']
20 default_env['TERM'] = ''
21 NINJA_PATH = os.path.abspath('./ninja')
22
23 def run(build_ninja, flags='', pipe=False, env=default_env):
24     with tempfile.TemporaryDirectory() as d:
25         os.chdir(d)
26         with open('build.ninja', 'w') as f:
27             f.write(build_ninja)
28             f.flush()
29         ninja_cmd = '{} {}'.format(NINJA_PATH, flags)
30         try:
31             if pipe:
32                 output = subprocess.check_output([ninja_cmd], shell=True, env=env)
33             elif platform.system() == 'Darwin':
34                 output = subprocess.check_output(['script', '-q', '/dev/null', 'bash', '-c', ninja_cmd],
35                                                  env=env)
36             else:
37                 output = subprocess.check_output(['script', '-qfec', ninja_cmd, '/dev/null'],
38                                                  env=env)
39         except subprocess.CalledProcessError as err:
40             sys.stdout.buffer.write(err.output)
41             raise err
42     final_output = ''
43     for line in output.decode('utf-8').splitlines(True):
44         if len(line) > 0 and line[-1] == '\r':
45             continue
46         final_output += line.replace('\r', '')
47     return final_output
48
49 @unittest.skipIf(platform.system() == 'Windows', 'These test methods do not work on Windows')
50 class Output(unittest.TestCase):
51     def test_issue_1418(self):
52         self.assertEqual(run(
53 '''rule echo
54   command = sleep $delay && echo $out
55   description = echo $out
56
57 build a: echo
58   delay = 3
59 build b: echo
60   delay = 2
61 build c: echo
62   delay = 1
63 ''', '-j3'),
64 '''[1/3] echo c\x1b[K
65 c
66 [2/3] echo b\x1b[K
67 b
68 [3/3] echo a\x1b[K
69 a
70 ''')
71
72     def test_issue_1214(self):
73         print_red = '''rule echo
74   command = printf '\x1b[31mred\x1b[0m'
75   description = echo $out
76
77 build a: echo
78 '''
79         # Only strip color when ninja's output is piped.
80         self.assertEqual(run(print_red),
81 '''[1/1] echo a\x1b[K
82 \x1b[31mred\x1b[0m
83 ''')
84         self.assertEqual(run(print_red, pipe=True),
85 '''[1/1] echo a
86 red
87 ''')
88         # Even in verbose mode, colors should still only be stripped when piped.
89         self.assertEqual(run(print_red, flags='-v'),
90 '''[1/1] printf '\x1b[31mred\x1b[0m'
91 \x1b[31mred\x1b[0m
92 ''')
93         self.assertEqual(run(print_red, flags='-v', pipe=True),
94 '''[1/1] printf '\x1b[31mred\x1b[0m'
95 red
96 ''')
97
98         # CLICOLOR_FORCE=1 can be used to disable escape code stripping.
99         env = default_env.copy()
100         env['CLICOLOR_FORCE'] = '1'
101         self.assertEqual(run(print_red, pipe=True, env=env),
102 '''[1/1] echo a
103 \x1b[31mred\x1b[0m
104 ''')
105
106     def test_pr_1685(self):
107         # Running those tools without .ninja_deps and .ninja_log shouldn't fail.
108         self.assertEqual(run('', flags='-t recompact'), '')
109         self.assertEqual(run('', flags='-t restat'), '')
110
111     def test_status(self):
112         self.assertEqual(run(''), 'ninja: no work to do.\n')
113
114 if __name__ == '__main__':
115     unittest.main()