Skip to content

Instantly share code, notes, and snippets.

@bebraw
Created January 10, 2010 10:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bebraw/273422 to your computer and use it in GitHub Desktop.
Save bebraw/273422 to your computer and use it in GitHub Desktop.
import inspect
class Commands(list):
def __init__(self, commands):
commands = commands if commands else []
if not hasattr(commands, '__iter__'):
commands = [commands]
super(Commands, self).__init__(commands)
def match(self, expression):
priorities = ('high', 'normal', 'low')
for priority in priorities:
commands = self.find(priority=priority)
for command in commands:
if command.matches(expression):
return command
def find(self, priority):
return filter(lambda command: command.priority == priority, self)
class Interpreter:
def __init__(self, commands=None):
self.commands = Commands(commands)
self.variables = {}
def interpret(self, expression):
possible_parameters = {'commands': self.commands,
'expression': expression, 'variables': self.variables}
try:
command = self.commands.match(expression)
args = self._get_args(command.execute)
params = self._find_parameters(possible_parameters, args)
return command.execute(**params)
except:
return 'null'
def _get_args(self, method):
return inspect.getargspec(method).args
def _find_parameters(self, possible_parameters, args):
ret = {}
for name, value in possible_parameters.items():
if name in args:
ret[name] = value
return ret
from mock import Mock
from placidity.interpreter import Interpreter
# TODO: convert execute asserts to assert_called_with and handle
# return with return_value. Note that it's possible to mock the
# signatures in Mock 0.7 (fix after release or include svn version in
# /lib)
class TestInterpreter:
def test_exception(self):
interpreter = Interpreter()
assert interpreter.interpret('foobar') == 'null'
def test_no_return(self):
def execute():
pass
command = self.create_command('foo', execute_method=execute)
interpreter = Interpreter(command)
assert interpreter.interpret('foo') == None
def test_priority(self):
def execute_1():
return 'foo'
command1 = self.create_command('bar', 'high', execute_1)
def execute_2():
return 'BYE'
command2 = self.create_command('bar', 'normal', execute_2)
def execute_3():
return 'BYEBYE'
command3 = self.create_command('bar', 'low', execute_3)
interpreter = Interpreter([command1, command2, command3])
assert interpreter.interpret('bar') == 'foo'
def test_execute_parameters(self):
def no_parameters():
return 'executed command'
def with_commands(commands):
assert commands == [command, ]
return 'executed command'
def with_expression(expression):
assert expression == 'command'
return 'executed command'
def with_variables(variables):
assert variables == {}
return 'executed command'
def with_multiple_parameters(expression, commands,
variables):
assert commands == [command, ]
assert expression == 'command'
assert variables == {}
return 'executed command'
execute_methods = (no_parameters, with_commands, with_expression, \
with_variables, with_multiple_parameters, )
command = self.create_command('command')
interpreter = Interpreter(command)
for execute_method in execute_methods:
command.execute = execute_method
assert interpreter.interpret('command') == 'executed command', \
execute_method.__name__ + ' failed!'
command.matches.assert_called_with('command')
def test_execute_command(self):
def execute():
return 'executed command'
command1 = self.create_command('foo', execute_method=execute)
command2 = self.create_command('bar', execute_method=execute)
interpreter = Interpreter([command1, command2, ])
assert interpreter.interpret('foo') == 'executed command'
def create_command(self, name, priority='normal', execute_method=None):
command = Mock()
command.aliases = name
command.matches = Mock()
command.matches.return_value = True
if execute_method:
command.execute = execute_method
command.priority = priority
return command
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment