Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
import inspect
class Context:
owner = None
def claim_for(self, owner):
self.owner = owner
def release(self):
self.owner = None
class Commands(list):
def __init__(self, commands=None):
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, name=None, priority=None):
if name:
for command in self:
class_name = command.__class__.__name__
if class_name.lower() == name:
return command
if priority:
return filter(lambda command: command.priority == priority, self)
class Interpreter:
def __init__(self, commands=None):
self.context = Context()
self.commands = Commands(commands)
self.variables = {}
def interpret(self, expression):
possible_parameters = {'context': self.context,
'commands': self.commands, 'expression': expression,
'variables': self.variables}
if self.context.owner:
command = self.context.owner
command = self.commands.match(expression)
args = self._get_args(command.execute)
params = self._find_parameters(possible_parameters, args)
return command.execute(**params)
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 Context, Commands, 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 TestContext:
def setup_method(self, method):
self.context = Context()
def test_claim_for(self):
assert self.context.owner == None
assert self.context.owner == 'foobar'
def test_release(self):
assert self.context.owner == 'barfoo'
assert self.context.owner == None
class TestCommands:
def test_find_single(self):
class Foo:
command = Foo()
commands = Commands(command)
assert commands.find(name='foo') == command
def test_find_nothing(self):
commands = Commands()
assert commands.find(name='foo') == None
def test_find_based_on_priority(self):
class Bar:
priority = 'low'
class Foo:
priority = 'normal'
class Help:
priority = 'normal'
command1 = Bar()
command2 = Foo()
command3 = Help()
commands = Commands((command1, command2, command3))
assert commands.find(priority='low') == [command1, ]
multiple = commands.find(priority='normal')
assert command2 in multiple
assert command3 in multiple
class TestInterpreter:
def test_exception(self):
interpreter = Interpreter()
assert interpreter.interpret('foobar') == 'null'
def test_context_owner_set(self):
def execute_1():
return 'foo'
command1 = self.create_command('foobar', execute_method=execute_1)
def execute_2(expression):
if expression == 'foobar':
return None
return 'bar'
command2 = self.create_command('bar', execute_method=execute_2)
interpreter = Interpreter([command1, command2])
assert interpreter.interpret('foobar') == None
assert interpreter.interpret('bar') == 'bar'
def test_no_return(self):
def execute():
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_context(context):
assert context.owner == None
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, context):
assert context.owner == None
assert commands == [command, ]
assert expression == 'command'
assert variables == {}
return 'executed command'
execute_methods = (no_parameters, with_context, 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!'
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