Created
January 10, 2010 10:08
-
-
Save bebraw/273422 to your computer and use it in GitHub Desktop.
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
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 |
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
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