Files
plac/doc/test_plac.py
2010-09-06 01:32:36 -04:00

224 lines
6.7 KiB
Python

"""
The tests are runnable with nose, with py.test, or even as standalone script
"""
import os, sys, doctest, subprocess
import plac
sys_argv0 = sys.argv[0]
os.chdir(os.path.dirname(__file__) or '.') # work in the current directory
######################## helpers #######################
def expect(errclass, func, *args, **kw):
try:
func(*args, **kw)
except errclass:
pass
else:
raise RuntimeError('%s expected, got none!', errclass.__name__)
def parser_from(f, **kw):
f.__annotations__ = kw
return plac.parser_from(f)
def check_help(name):
sys.argv[0] = name + '.py' # avoid issue with nosetests
plac.parser_registry.clear() # makes different imports independent
try:
try:
main = plac.import_main(name + '.py')
except SyntaxError:
if sys.version < '3': # expected for Python 2.X
return
else: # not expected for Python 3.X
raise
p = plac.parser_from(main)
expected = open(name + '.help').read().strip()
got = p.format_help().strip()
assert got == expected, got
finally:
sys.argv[0] = sys_argv0
####################### tests ############################
def test_expected_help():
for fname in os.listdir('.'):
if fname.endswith('.help'):
name = fname[:-5]
if name not in ('vcs', 'ishelve'):
yield check_help, fname[:-5]
p1 = parser_from(lambda delete, *args: None,
delete=('delete a file', 'option'))
def test_p1():
arg = p1.parse_args(['-d', 'foo', 'arg1', 'arg2'])
assert arg.delete == 'foo'
assert arg.args == ['arg1', 'arg2']
arg = p1.parse_args([])
assert arg.delete is None, arg.delete
assert arg.args == [], arg.args
p2 = parser_from(lambda arg1, delete, *args: None,
delete=('delete a file', 'option', 'd'))
def test_p2():
arg = p2.parse_args(['-d', 'foo', 'arg1', 'arg2'])
assert arg.delete == 'foo', arg.delete
assert arg.arg1 == 'arg1', arg.arg1
assert arg.args == ['arg2'], arg.args
arg = p2.parse_args(['arg1'])
assert arg.delete is None, arg.delete
assert arg.args == [], arg.args
assert arg, arg
expect(SystemExit, p2.parse_args, [])
p3 = parser_from(lambda arg1, delete: None,
delete=('delete a file', 'option', 'd'))
def test_p3():
arg = p3.parse_args(['arg1'])
assert arg.delete is None, arg.delete
assert arg.arg1 == 'arg1', arg.args
expect(SystemExit, p3.parse_args, ['arg1', 'arg2'])
expect(SystemExit, p3.parse_args, [])
p4 = parser_from(lambda delete, delete_all, color="black": None,
delete=('delete a file', 'option', 'd'),
delete_all=('delete all files', 'flag', 'a'),
color=('color', 'option', 'c'))
def test_p4():
arg = p4.parse_args(['-a'])
assert arg.delete_all is True, arg.delete_all
arg = p4.parse_args([])
arg = p4.parse_args(['--color=black'])
assert arg.color == 'black'
arg = p4.parse_args(['--color=red'])
assert arg.color == 'red'
def test_flag_with_default():
expect(TypeError, parser_from, lambda yes_or_no='no': None,
yes_or_no=('A yes/no flag', 'flag', 'f'))
def assert_usage(parser, expected):
usage = parser.format_usage()
assert usage == expected, usage
def test_metavar_no_defaults():
sys.argv[0] = 'test_plac.py'
# positional
p = parser_from(lambda x: None,
x=('first argument', 'positional', None, str, [], 'METAVAR'))
assert_usage(p, 'usage: test_plac.py [-h] METAVAR\n')
# option
p = parser_from(lambda x: None,
x=('first argument', 'option', None, str, [], 'METAVAR'))
assert_usage(p, 'usage: test_plac.py [-h] [-x METAVAR]\n')
sys.argv[0] = sys_argv0
def test_metavar_with_defaults():
sys.argv[0] = 'test_plac.py'
# positional
p = parser_from(lambda x='a': None,
x=('first argument', 'positional', None, str, [], 'METAVAR'))
assert_usage(p, 'usage: test_plac.py [-h] [METAVAR]\n')
# option
p = parser_from(lambda x='a': None,
x=('first argument', 'option', None, str, [], 'METAVAR'))
assert_usage(p, 'usage: test_plac.py [-h] [-x METAVAR]\n')
p = parser_from(lambda x='a': None,
x=('first argument', 'option', None, str, []))
assert_usage(p, 'usage: test_plac.py [-h] [-x a]\n')
sys.argv[0] = sys_argv0
def test_kwargs():
def main(opt, arg1, *args, **kw):
print(opt, arg1)
return args, kw
main.__annotations__ = dict(opt=('Option', 'option'))
argskw = plac.call(main, ['arg1', 'arg2', 'a=1', 'b=2'])
assert argskw == [('arg2',), {'a': '1', 'b': '2'}], argskw
argskw = plac.call(main, ['arg1', 'arg2', 'a=1', '-o', '2'])
assert argskw == [('arg2',), {'a': '1'}], argskw
expect(SystemExit, plac.call, main, ['arg1', 'arg2', 'a=1', 'opt=2'])
class Cmds(object):
add_help = False
commands = 'help', 'commit'
def help(self, name):
return 'help', name
def commit(self):
return 'commit'
cmds = Cmds()
def test_cmds():
assert 'commit' == plac.call(cmds, ['commit'])
assert ['help', 'foo'] == plac.call(cmds, ['help', 'foo'])
expect(SystemExit, plac.call, cmds, [])
def test_cmd_abbrevs():
assert 'commit' == plac.call(cmds, ['comm'])
assert ['help', 'foo'] == plac.call(cmds, ['h', 'foo'])
expect(SystemExit, plac.call, cmds, ['foo'])
def test_yield():
def main():
for i in (1, 2, 3):
yield i
assert plac.call(main, []) == [1, 2, 3]
def test_doctest():
failure, tot= doctest.testfile('plac.txt', module_relative=False)
assert not failure, failure
failing_scripts = set(['ishelve2.plac'])
def check_script(args):
if failing_scripts.intersection(args):
assert subprocess.call(args) > 0, ( # expected failure
'Unexpected success for %s' % ' '.join(args))
else:
assert subprocess.call(args) == 0 , 'Failed %s' % ' '.join(args)
def test_batch():
for batch in os.listdir('.'):
if batch.endswith('.plac'):
yield check_script, ['plac_runner.py', '-b', batch]
def test_placet():
for placet in os.listdir('.'):
if placet.endswith('.placet'):
yield check_script, ['plac_runner.py', '-t', placet]
if __name__ == '__main__':
n = 0
for name, test in sorted(globals().items()):
if name.startswith('test_'):
print('Running ' + name)
maybegen = test()
if hasattr(maybegen, '__iter__'):
for func, arg in maybegen:
func(arg)
n += 1
else:
n +=1
print('Executed %d tests OK' % n)