mirror of
https://github.com/python/cpython.git
synced 2025-01-27 11:33:55 +08:00
7905d61b2c
Cmd used to blindly chop off the last character of every input line. If the input reached EOF and there was no final new line, it would truncate the last character of the last command. This fix instead strips trailing \r\n from the input lines. While this is a small behavior change, it should not break any working code, since feeding a '\r\n' terminated file to Cmd would previously leave the \r's on the lines, resulting in failed command execution. I wrote the unit test in preparation for a PyOhio TeachMe session run by Catherine Devlin, and we can thank Catherine and the PyOhio session attendees for the fix. I've added Catherine to the Acks file for organizing and leading the TeachMe session, out of which we will hopefully get some new contributors.
216 lines
5.3 KiB
Python
216 lines
5.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script for the 'cmd' module
|
|
Original by Michael Schneider
|
|
"""
|
|
|
|
|
|
import cmd
|
|
import sys
|
|
import re
|
|
import unittest
|
|
import io
|
|
from test import support
|
|
|
|
class samplecmdclass(cmd.Cmd):
|
|
"""
|
|
Instance the sampleclass:
|
|
>>> mycmd = samplecmdclass()
|
|
|
|
Test for the function parseline():
|
|
>>> mycmd.parseline("")
|
|
(None, None, '')
|
|
>>> mycmd.parseline("?")
|
|
('help', '', 'help ')
|
|
>>> mycmd.parseline("?help")
|
|
('help', 'help', 'help help')
|
|
>>> mycmd.parseline("!")
|
|
('shell', '', 'shell ')
|
|
>>> mycmd.parseline("!command")
|
|
('shell', 'command', 'shell command')
|
|
>>> mycmd.parseline("func")
|
|
('func', '', 'func')
|
|
>>> mycmd.parseline("func arg1")
|
|
('func', 'arg1', 'func arg1')
|
|
|
|
|
|
Test for the function onecmd():
|
|
>>> mycmd.onecmd("")
|
|
>>> mycmd.onecmd("add 4 5")
|
|
9
|
|
>>> mycmd.onecmd("")
|
|
9
|
|
>>> mycmd.onecmd("test")
|
|
*** Unknown syntax: test
|
|
|
|
Test for the function emptyline():
|
|
>>> mycmd.emptyline()
|
|
*** Unknown syntax: test
|
|
|
|
Test for the function default():
|
|
>>> mycmd.default("default")
|
|
*** Unknown syntax: default
|
|
|
|
Test for the function completedefault():
|
|
>>> mycmd.completedefault()
|
|
This is the completedefault methode
|
|
>>> mycmd.completenames("a")
|
|
['add']
|
|
|
|
Test for the function completenames():
|
|
>>> mycmd.completenames("12")
|
|
[]
|
|
>>> mycmd.completenames("help")
|
|
['help']
|
|
|
|
Test for the function complete_help():
|
|
>>> mycmd.complete_help("a")
|
|
['add']
|
|
>>> mycmd.complete_help("he")
|
|
['help']
|
|
>>> mycmd.complete_help("12")
|
|
[]
|
|
>>> sorted(mycmd.complete_help(""))
|
|
['add', 'exit', 'help', 'shell']
|
|
|
|
Test for the function do_help():
|
|
>>> mycmd.do_help("testet")
|
|
*** No help on testet
|
|
>>> mycmd.do_help("add")
|
|
help text for add
|
|
>>> mycmd.onecmd("help add")
|
|
help text for add
|
|
>>> mycmd.do_help("")
|
|
<BLANKLINE>
|
|
Documented commands (type help <topic>):
|
|
========================================
|
|
add
|
|
<BLANKLINE>
|
|
Undocumented commands:
|
|
======================
|
|
exit help shell
|
|
<BLANKLINE>
|
|
|
|
Test for the function print_topics():
|
|
>>> mycmd.print_topics("header", ["command1", "command2"], 2 ,10)
|
|
header
|
|
======
|
|
command1
|
|
command2
|
|
<BLANKLINE>
|
|
|
|
Test for the function columnize():
|
|
>>> mycmd.columnize([str(i) for i in range(20)])
|
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
|
>>> mycmd.columnize([str(i) for i in range(20)], 10)
|
|
0 7 14
|
|
1 8 15
|
|
2 9 16
|
|
3 10 17
|
|
4 11 18
|
|
5 12 19
|
|
6 13
|
|
|
|
This is a interactive test, put some commands in the cmdqueue attribute
|
|
and let it execute
|
|
This test includes the preloop(), postloop(), default(), emptyline(),
|
|
parseline(), do_help() functions
|
|
>>> mycmd.use_rawinput=0
|
|
>>> mycmd.cmdqueue=["", "add", "add 4 5", "help", "help add","exit"]
|
|
>>> mycmd.cmdloop()
|
|
Hello from preloop
|
|
help text for add
|
|
*** invalid number of arguments
|
|
9
|
|
<BLANKLINE>
|
|
Documented commands (type help <topic>):
|
|
========================================
|
|
add
|
|
<BLANKLINE>
|
|
Undocumented commands:
|
|
======================
|
|
exit help shell
|
|
<BLANKLINE>
|
|
help text for add
|
|
Hello from postloop
|
|
"""
|
|
|
|
def preloop(self):
|
|
print("Hello from preloop")
|
|
|
|
def postloop(self):
|
|
print("Hello from postloop")
|
|
|
|
def completedefault(self, *ignored):
|
|
print("This is the completedefault methode")
|
|
|
|
def complete_command(self):
|
|
print("complete command")
|
|
|
|
def do_shell(self, s):
|
|
pass
|
|
|
|
def do_add(self, s):
|
|
l = s.split()
|
|
if len(l) != 2:
|
|
print("*** invalid number of arguments")
|
|
return
|
|
try:
|
|
l = [int(i) for i in l]
|
|
except ValueError:
|
|
print("*** arguments should be numbers")
|
|
return
|
|
print(l[0]+l[1])
|
|
|
|
def help_add(self):
|
|
print("help text for add")
|
|
return
|
|
|
|
def do_exit(self, arg):
|
|
return True
|
|
|
|
|
|
class TestAlternateInput(unittest.TestCase):
|
|
|
|
class simplecmd(cmd.Cmd):
|
|
|
|
def do_print(self, args):
|
|
print(args, file=self.stdout)
|
|
|
|
def do_EOF(self, args):
|
|
return True
|
|
|
|
def test_file_with_missing_final_nl(self):
|
|
input = io.StringIO("print test\nprint test2")
|
|
output = io.StringIO()
|
|
cmd = self.simplecmd(stdin=input, stdout=output)
|
|
cmd.use_rawinput = False
|
|
cmd.cmdloop()
|
|
self.assertMultiLineEqual(output.getvalue(),
|
|
("(Cmd) test\n"
|
|
"(Cmd) test2\n"
|
|
"(Cmd) "))
|
|
|
|
|
|
def test_main(verbose=None):
|
|
from test import test_cmd
|
|
support.run_doctest(test_cmd, verbose)
|
|
support.run_unittest(TestAlternateInput)
|
|
|
|
def test_coverage(coverdir):
|
|
trace = support.import_module('trace')
|
|
tracer=trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,],
|
|
trace=0, count=1)
|
|
tracer.run('reload(cmd);test_main()')
|
|
r=tracer.results()
|
|
print("Writing coverage results...")
|
|
r.write_results(show_missing=True, summary=True, coverdir=coverdir)
|
|
|
|
if __name__ == "__main__":
|
|
if "-c" in sys.argv:
|
|
test_coverage('/tmp/cmd.cover')
|
|
elif "-i" in sys.argv:
|
|
samplecmdclass().cmdloop()
|
|
else:
|
|
test_main()
|