forked from prophile/compd
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
95 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
"""compctl | ||
Usage: | ||
compctl halt | ||
compctl usage | ||
""" | ||
|
||
import shlex | ||
import re | ||
from docopt import docopt, DocoptExit | ||
|
||
class CommandError(Exception): | ||
pass | ||
|
||
def parse(cmd): | ||
parts = shlex.split(cmd) | ||
try: | ||
options = docopt(__doc__, argv = parts, | ||
help = False, version = None) | ||
return options | ||
except DocoptExit: | ||
raise CommandError() | ||
|
||
HANDLERS = {} | ||
|
||
def handler(subcommand): | ||
def wrapper(fn): | ||
HANDLERS[subcommand] = fn | ||
return fn | ||
return wrapper | ||
|
||
def dispatch(options, responder): | ||
for name, callback in HANDLERS.iteritems(): | ||
if options[name]: | ||
callback(responder, options) | ||
return | ||
raise CommandError() | ||
|
||
@handler('usage') | ||
def handle_usage(responder, opts): | ||
regex = re.compile(' compctl (.*)') | ||
for line in __doc__.split('\n')[3:]: | ||
match = regex.match(line) | ||
if match: | ||
responder('Usage: {0}'.format(match.group(1))) | ||
|
||
@handler('halt') | ||
def halt_system(responder, options): | ||
import sys | ||
responder("System going down for halt") | ||
sys.exit(0) | ||
|
||
def default_responder(output): | ||
print output | ||
|
||
def handle(cmd, responder = default_responder, no_auto_fail = False): | ||
try: | ||
dispatch(parse(cmd), responder) | ||
except CommandError: | ||
if no_auto_fail: | ||
raise | ||
else: | ||
handle('usage', responder, no_auto_fail = True) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import control | ||
import mock | ||
import sys | ||
|
||
def test_halt_parse(): | ||
options = control.parse('halt') | ||
assert options['halt'] | ||
|
||
def check_showed_usage(responder): | ||
responder.assert_any_call('Usage: halt') | ||
responder.assert_any_call('Usage: usage') | ||
|
||
def test_usage(): | ||
responder = mock.Mock() | ||
control.handle('usage', responder) | ||
check_showed_usage(responder) | ||
|
||
def test_halt(): | ||
exit_handler = mock.Mock() | ||
responder = mock.Mock() | ||
with mock.patch('sys.exit', exit_handler): | ||
control.handle('halt', responder) | ||
responder.assert_called_once_with('System going down for halt') | ||
exit_handler.assert_called_once_with(0) | ||
|
||
def test_unknown(): | ||
responder = mock.Mock() | ||
control.handle('hnnnng', responder) | ||
check_showed_usage(responder) | ||
|