1"""
2Test script for the 'cmd' module
3Original by Michael Schneider
4"""
5
6
7import cmd
8import sys
9import doctest
10import unittest
11import io
12from test import support
13
14class samplecmdclass(cmd.Cmd):
15    """
16    Instance the sampleclass:
17    >>> mycmd = samplecmdclass()
18
19    Test for the function parseline():
20    >>> mycmd.parseline("")
21    (None, None, '')
22    >>> mycmd.parseline("?")
23    ('help', '', 'help ')
24    >>> mycmd.parseline("?help")
25    ('help', 'help', 'help help')
26    >>> mycmd.parseline("!")
27    ('shell', '', 'shell ')
28    >>> mycmd.parseline("!command")
29    ('shell', 'command', 'shell command')
30    >>> mycmd.parseline("func")
31    ('func', '', 'func')
32    >>> mycmd.parseline("func arg1")
33    ('func', 'arg1', 'func arg1')
34
35
36    Test for the function onecmd():
37    >>> mycmd.onecmd("")
38    >>> mycmd.onecmd("add 4 5")
39    9
40    >>> mycmd.onecmd("")
41    9
42    >>> mycmd.onecmd("test")
43    *** Unknown syntax: test
44
45    Test for the function emptyline():
46    >>> mycmd.emptyline()
47    *** Unknown syntax: test
48
49    Test for the function default():
50    >>> mycmd.default("default")
51    *** Unknown syntax: default
52
53    Test for the function completedefault():
54    >>> mycmd.completedefault()
55    This is the completedefault method
56    >>> mycmd.completenames("a")
57    ['add']
58
59    Test for the function completenames():
60    >>> mycmd.completenames("12")
61    []
62    >>> mycmd.completenames("help")
63    ['help']
64
65    Test for the function complete_help():
66    >>> mycmd.complete_help("a")
67    ['add']
68    >>> mycmd.complete_help("he")
69    ['help']
70    >>> mycmd.complete_help("12")
71    []
72    >>> sorted(mycmd.complete_help(""))
73    ['add', 'exit', 'help', 'shell']
74
75    Test for the function do_help():
76    >>> mycmd.do_help("testet")
77    *** No help on testet
78    >>> mycmd.do_help("add")
79    help text for add
80    >>> mycmd.onecmd("help add")
81    help text for add
82    >>> mycmd.do_help("")
83    <BLANKLINE>
84    Documented commands (type help <topic>):
85    ========================================
86    add  help
87    <BLANKLINE>
88    Undocumented commands:
89    ======================
90    exit  shell
91    <BLANKLINE>
92
93    Test for the function print_topics():
94    >>> mycmd.print_topics("header", ["command1", "command2"], 2 ,10)
95    header
96    ======
97    command1
98    command2
99    <BLANKLINE>
100
101    Test for the function columnize():
102    >>> mycmd.columnize([str(i) for i in range(20)])
103    0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19
104    >>> mycmd.columnize([str(i) for i in range(20)], 10)
105    0  7   14
106    1  8   15
107    2  9   16
108    3  10  17
109    4  11  18
110    5  12  19
111    6  13
112
113    This is an interactive test, put some commands in the cmdqueue attribute
114    and let it execute
115    This test includes the preloop(), postloop(), default(), emptyline(),
116    parseline(), do_help() functions
117    >>> mycmd.use_rawinput=0
118    >>> mycmd.cmdqueue=["", "add", "add 4 5", "help", "help add","exit"]
119    >>> mycmd.cmdloop()
120    Hello from preloop
121    help text for add
122    *** invalid number of arguments
123    9
124    <BLANKLINE>
125    Documented commands (type help <topic>):
126    ========================================
127    add  help
128    <BLANKLINE>
129    Undocumented commands:
130    ======================
131    exit  shell
132    <BLANKLINE>
133    help text for add
134    Hello from postloop
135    """
136
137    def preloop(self):
138        print("Hello from preloop")
139
140    def postloop(self):
141        print("Hello from postloop")
142
143    def completedefault(self, *ignored):
144        print("This is the completedefault method")
145
146    def complete_command(self):
147        print("complete command")
148
149    def do_shell(self, s):
150        pass
151
152    def do_add(self, s):
153        l = s.split()
154        if len(l) != 2:
155            print("*** invalid number of arguments")
156            return
157        try:
158            l = [int(i) for i in l]
159        except ValueError:
160            print("*** arguments should be numbers")
161            return
162        print(l[0]+l[1])
163
164    def help_add(self):
165        print("help text for add")
166        return
167
168    def do_exit(self, arg):
169        return True
170
171
172class TestAlternateInput(unittest.TestCase):
173
174    class simplecmd(cmd.Cmd):
175
176        def do_print(self, args):
177            print(args, file=self.stdout)
178
179        def do_EOF(self, args):
180            return True
181
182
183    class simplecmd2(simplecmd):
184
185        def do_EOF(self, args):
186            print('*** Unknown syntax: EOF', file=self.stdout)
187            return True
188
189
190    def test_file_with_missing_final_nl(self):
191        input = io.StringIO("print test\nprint test2")
192        output = io.StringIO()
193        cmd = self.simplecmd(stdin=input, stdout=output)
194        cmd.use_rawinput = False
195        cmd.cmdloop()
196        self.assertMultiLineEqual(output.getvalue(),
197            ("(Cmd) test\n"
198             "(Cmd) test2\n"
199             "(Cmd) "))
200
201
202    def test_input_reset_at_EOF(self):
203        input = io.StringIO("print test\nprint test2")
204        output = io.StringIO()
205        cmd = self.simplecmd2(stdin=input, stdout=output)
206        cmd.use_rawinput = False
207        cmd.cmdloop()
208        self.assertMultiLineEqual(output.getvalue(),
209            ("(Cmd) test\n"
210             "(Cmd) test2\n"
211             "(Cmd) *** Unknown syntax: EOF\n"))
212        input = io.StringIO("print \n\n")
213        output = io.StringIO()
214        cmd.stdin = input
215        cmd.stdout = output
216        cmd.cmdloop()
217        self.assertMultiLineEqual(output.getvalue(),
218            ("(Cmd) \n"
219             "(Cmd) \n"
220             "(Cmd) *** Unknown syntax: EOF\n"))
221
222
223def load_tests(loader, tests, pattern):
224    tests.addTest(doctest.DocTestSuite())
225    return tests
226
227def test_coverage(coverdir):
228    trace = support.import_module('trace')
229    tracer=trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,],
230                        trace=0, count=1)
231    tracer.run('import importlib; importlib.reload(cmd); test_main()')
232    r=tracer.results()
233    print("Writing coverage results...")
234    r.write_results(show_missing=True, summary=True, coverdir=coverdir)
235
236if __name__ == "__main__":
237    if "-c" in sys.argv:
238        test_coverage('/tmp/cmd.cover')
239    elif "-i" in sys.argv:
240        samplecmdclass().cmdloop()
241    else:
242        unittest.main()
243