1# coding: utf-8 2""" 3Regression tests 4~~~~~~~~~~~~~~~~ 5""" 6import pytest 7import argh 8 9from .base import DebugArghParser, run 10 11 12def test_regression_issue12(): 13 """ 14 Issue #12: @command was broken if there were more than one argument 15 to begin with same character (i.e. short option names were inferred 16 incorrectly). 17 """ 18 19 def cmd(foo=1, fox=2): 20 yield 'foo {0}, fox {1}'.format(foo, fox) 21 22 p = DebugArghParser() 23 p.set_default_command(cmd) 24 25 assert run(p, '').out == 'foo 1, fox 2\n' 26 assert run(p, '--foo 3').out == 'foo 3, fox 2\n' 27 assert run(p, '--fox 3').out == 'foo 1, fox 3\n' 28 assert 'unrecognized' in run(p, '-f 3', exit=True) 29 30 31def test_regression_issue12_help_flag(): 32 """ 33 Issue #12: if an argument starts with "h", e.g. "--host", 34 ArgumentError is raised because "--help" is always added by argh 35 without decorators. 36 """ 37 def ddos(host='localhost'): 38 return 'so be it, {0}!'.format(host) 39 40 # no help → no conflict 41 p = DebugArghParser('PROG', add_help=False) 42 p.set_default_command(ddos) 43 assert run(p, '-h 127.0.0.1').out == 'so be it, 127.0.0.1!\n' 44 45 # help added → conflict → short name ignored 46 p = DebugArghParser('PROG', add_help=True) 47 p.set_default_command(ddos) 48 assert None == run(p, '-h 127.0.0.1', exit=True) 49 50 51def test_regression_issue27(): 52 """ 53 Issue #27: store_true is not set for inferred bool argument. 54 55 :Reason: when @command was refactored, it stopped using @arg, but it is 56 it was there that guesses (choices→type, default→type and 57 default→action) were made. 58 """ 59 def parrot(dead=False): 60 return 'this parrot is no more' if dead else 'beautiful plumage' 61 62 def grenade(count=3): 63 if count == 3: 64 return 'Three shall be the number thou shalt count' 65 else: 66 return '{0!r} is right out'.format(count) 67 68 p = DebugArghParser() 69 p.add_commands([parrot, grenade]) 70 71 # default → type (int) 72 assert run(p, 'grenade').out == ('Three shall be the number ' 73 'thou shalt count\n') 74 assert run(p, 'grenade --count 5').out == '5 is right out\n' 75 76 # default → action (store_true) 77 assert run(p, 'parrot').out == 'beautiful plumage\n' 78 assert run(p, 'parrot --dead').out == 'this parrot is no more\n' 79 80 81def test_regression_issue31(): 82 """ 83 Issue #31: Argh fails with parameter action type 'count' if a default 84 value is provided. 85 86 :Reason: assembling._guess() would infer type from default value without 87 regard to the action. _CountAction does not accept argument "type". 88 89 :Solution: restricted type inferring to actions "store" and "append". 90 """ 91 92 @argh.arg('-v', '--verbose', dest='verbose', action='count', default=0) 93 def cmd(**kwargs): 94 yield kwargs.get('verbose', -1) 95 96 p = DebugArghParser() 97 p.set_default_command(cmd) 98 assert '0\n' == run(p, '').out 99 assert '1\n' == run(p, '-v').out 100 assert '2\n' == run(p, '-vv').out 101 102 103def test_regression_issue47(): 104 @argh.arg('--foo-bar', default="full") 105 def func(foo_bar): 106 return 'hello' 107 108 p = DebugArghParser() 109 with pytest.raises(argh.assembling.AssemblingError) as excinfo: 110 p.set_default_command(func) 111 msg = ('func: argument "foo_bar" declared as positional (in function ' 112 'signature) and optional (via decorator)') 113 assert excinfo.exconly().endswith(msg) 114 115 116def test_regression_issue76(): 117 """ 118 Issue #76: optional arguments defaulting to the empty string break --help. 119 120 This is also tested in integration tests but in a different way. 121 """ 122 def cmd(foo=''): 123 pass 124 125 p = DebugArghParser() 126 p.set_default_command(cmd) 127 run(p, '--help', exit=True) 128