OILS / core / comp_ui_test.py View on Github | oils.pub

177 lines, 118 significant
1#!/usr/bin/env python2
2from __future__ import print_function
3
4import cStringIO
5import sys
6import unittest
7
8from core import comp_ui # module under test
9from core import util
10from mycpp import iolib
11
12import line_input
13
14
15class VisualTest(unittest.TestCase):
16
17 def testPrintPacked(self):
18 matches = ['foo', 'bar', 'spam', 'eggs', 'python', 'perl']
19 longest_match_len = max(len(m) for m in matches)
20 max_lines = 10
21
22 for width in (1, 10, 20, 30, 40, 50):
23 f = cStringIO.StringIO()
24 n = comp_ui._PrintPacked(matches, longest_match_len, width,
25 max_lines, f)
26
27 out = f.getvalue()
28 lines = out.splitlines()
29 max_len = max(len(line) for line in lines)
30
31 print('WIDTH = %d' % width)
32 print('reported lines = %d' % n)
33 print('measured lines = %d' % len(lines))
34 print('max_len = %d' % max_len)
35
36 # Make sure it fits in the width!
37
38 # NOTE: This is too conservative because of non-printable characters
39 # like \n and ANSI escapes
40 if width != 1:
41 self.assertLess(max_len, width)
42
43 print('')
44
45 def testLongStringAndSkinnyTerminal(self):
46 matches = ['foo' * 10, 'bar' * 10, 'spams' * 10, 'zzz']
47 longest_match_len = max(len(m) for m in matches)
48
49 for width in (1, 10, 20, 30, 40, 50):
50 f = cStringIO.StringIO()
51 n = comp_ui._PrintPacked(matches, longest_match_len, width, 10, f)
52
53 out = f.getvalue()
54 lines = out.splitlines()
55 max_len = max(len(line) for line in lines)
56
57 print('WIDTH = %d' % width)
58 print('reported lines = %d' % n)
59 print('measured lines = %d' % len(lines))
60 print('max_len = %d' % max_len)
61 print('')
62
63 def testTooMany(self):
64 matches = ['--flag%d' % i for i in xrange(100)]
65 longest_match_len = max(len(m) for m in matches)
66
67 for width in (1, 10, 20, 30, 40, 50, 60):
68 f = cStringIO.StringIO()
69 n = comp_ui._PrintPacked(matches, longest_match_len, width, 10, f)
70
71 out = f.getvalue()
72 lines = out.splitlines()
73 max_len = max(len(line) for line in lines)
74
75 print('WIDTH = %d' % width)
76 print('reported lines = %d' % n)
77 # Count newlines since last one doesn't have a newline
78 print('measured lines = %d' % out.count('\n'))
79 print('max_len = %d' % max_len)
80 print('')
81
82 #print(out)
83
84 def testPrintLong(self):
85 matches = ['--all', '--almost-all', '--verbose']
86 longest_match_len = max(len(m) for m in matches)
87 descriptions = {
88 '--all': 'show all ' * 10, # truncate
89 '--almost-all': 'foo',
90 '--verbose': 'bar'
91 }
92
93 max_lines = 10
94 for width in (1, 10, 20, 30, 40, 50, 60):
95 f = cStringIO.StringIO()
96 n = comp_ui._PrintLong(matches, longest_match_len, width,
97 max_lines, descriptions, f)
98
99 out = f.getvalue()
100 lines = out.splitlines()
101 max_len = max(len(line) for line in lines)
102
103 print('WIDTH = %d' % width)
104 print('reported lines = %d' % n)
105 # Count newlines since last one doesn't have a newline
106 print('measured lines = %d' % out.count('\n'))
107 print('max_len = %d' % max_len)
108 print('')
109
110 #print(out)
111
112
113class UiTest(unittest.TestCase):
114
115 def testDisplays(self):
116 comp_ui_state = comp_ui.State()
117 prompt_state = comp_ui.PromptState()
118 debug_f = util.DebugFile(sys.stdout)
119 signal_safe = iolib.InitSignalSafe()
120
121 # terminal width
122 d1 = comp_ui.NiceDisplay(comp_ui_state, prompt_state, debug_f,
123 line_input, signal_safe)
124 d2 = comp_ui.MinimalDisplay(comp_ui_state, prompt_state, debug_f,
125 signal_safe)
126
127 prompt_state.SetLastPrompt('$ ')
128
129 for disp in [d1, d2]:
130 # This one is important
131 disp.EraseLines()
132 disp.Reset()
133
134 # These are related but we can just set them separately.
135 comp_ui_state.line_until_tab = 'echo ' # for returning to the prompt
136 comp_ui_state.display_pos = 5 # Strip this off every candidate
137
138 disp.PrintRequired('hello')
139 disp.PrintOptional('hello')
140
141 matches = ['echo one', 'echo two']
142 disp.PrintCandidates(None, matches, None)
143
144 # This needs to be aware of the terminal width.
145 # It's a bit odd since it's called as a side effect of the PromptEvaluator.
146 # That class knows about styles and so forth.
147
148 disp.ShowPromptOnRight('RIGHT')
149
150
151class PromptTest(unittest.TestCase):
152
153 def testNoEscapes(self):
154 for prompt in ["> ", "osh>", "[[]][[]][][]]][["]:
155 self.assertEqual(comp_ui._PromptLen(prompt), len(prompt))
156
157 def testValidEscapes(self):
158 self.assertEqual(
159 comp_ui._PromptLen("\x01\033[01;34m\x02user\x01\033[00m\x02 >"),
160 len("user >"))
161 self.assertEqual(comp_ui._PromptLen("\x01\x02\x01\x02\x01\x02"), 0)
162 self.assertEqual(
163 comp_ui._PromptLen("\x01\x02 hi \x01hi\x02 \x01\x02 hello"),
164 len(" hi hello"))
165
166 def testNewline(self):
167 self.assertEqual(comp_ui._PromptLen("\n"), 0)
168 self.assertEqual(comp_ui._PromptLen("abc\ndef"), 3)
169 self.assertEqual(comp_ui._PromptLen(""), 0)
170
171 def testControlCharacters(self):
172 self.assertEqual(comp_ui._PromptLen("\xef"), 1)
173 self.assertEqual(comp_ui._PromptLen("\x03\x05"), 2)
174
175
176if __name__ == '__main__':
177 unittest.main()