class TestCommandManager(unittest.TestCase): def setUp(self): self.command_manager = CommandManager(Message()) def test_register_command(self): def _test(): pass test_dict = {'blah': _test} self.command_manager.register_command('test', test_dict) self.assertIn('test', self.command_manager._commands) self.assertFalse(self.command_manager.is_command('test')) self.assertFalse(self.command_manager.is_command('blah')) self.command_manager.register_command('blah', _test) self.assertTrue(self.command_manager.is_command('blah')) # FIXME: ? self.assertTrue(self.command_manager.is_command('test blah')) def test_help(self): message = vexmessage.Message('target', 'source', 'CMD', command='help') self.command_manager.parse_commands(message) response_sent = self.command_manager._messaging.response[1] self.assertIn('response', response_sent) message = vexmessage.Message('target', 'source', 'CMD', command='help commands') self.command_manager.parse_commands(message) response_sent = self.command_manager._messaging.response[1]['response'] self.assertIn('help', response_sent) self.assertIn('commands', response_sent) def test_help_specific(self): message = vexmessage.Message('target', 'source', 'CMD', command='help', args=['commands']) self.command_manager.parse_commands(message) response = self.command_manager._messaging.response self.assertIsNotNone(response) def test_commands(self): message = vexmessage.Message('target', 'source', 'CMD', command='commands') self.command_manager.parse_commands(message) response_sent = self.command_manager._messaging.response answer = response_sent[1]['response'] self.assertIn('commands', answer) self.assertIn('help', answer) def test_is_command_with_call(self): def t(*args): pass self.command_manager.register_command('t', t) called = self.command_manager.is_command('t', True) self.assertTrue(called) not_called = self.command_manager.is_command('f', True) self.assertFalse(not_called) # FIXME: not sure what actually want here called_w_args = self.command_manager.is_command('t these are args', True) self.assertTrue(called_w_args) def test_get_callback_recursively_none(self): result = self.command_manager._get_callback_recursively(None) self.assertEqual(len(result), 3) for r in result: self.assertIsNone(r) def test_cmd_commands(self): def t(): pass self.command_manager.register_command('test', t) nested = {'test': t} self.command_manager.register_command('nested', nested) commands = self.command_manager._cmd_commands(None) self.assertIn('test', commands) self.assertIn('nested test', commands) self.assertNotIn('blah', commands) # TODO: test `help` and `commands`? self.assertEqual(len(commands), 4)
class TestCommandManager(unittest.TestCase): def setUp(self): self.command_manager = CommandManager(Message()) def test_register_command(self): def _test(): pass test_dict = {'blah': _test} self.command_manager.register_command('test', test_dict) self.assertIn('test', self.command_manager._commands) self.assertFalse(self.command_manager.is_command('test')) self.assertFalse(self.command_manager.is_command('blah')) self.command_manager.register_command('blah', _test) self.assertTrue(self.command_manager.is_command('blah')) # FIXME: ? self.assertTrue(self.command_manager.is_command('test blah')) def test_help(self): message = vexmessage.Message('target', 'source', 'CMD', command='help') self.command_manager.parse_commands(message) response_sent = self.command_manager._messaging.response[1] self.assertIn('response', response_sent) message = vexmessage.Message('target', 'source', 'CMD', command='help commands') self.command_manager.parse_commands(message) response_sent = self.command_manager._messaging.response[1]['response'] self.assertIn('help', response_sent) self.assertIn('commands', response_sent) def test_help_specific(self): message = vexmessage.Message('target', 'source', 'CMD', command='help', args=['commands']) self.command_manager.parse_commands(message) response = self.command_manager._messaging.response self.assertIsNotNone(response) def test_commands(self): message = vexmessage.Message('target', 'source', 'CMD', command='commands') self.command_manager.parse_commands(message) response_sent = self.command_manager._messaging.response answer = response_sent[1]['response'] self.assertIn('commands', answer) self.assertIn('help', answer) def test_is_command_with_call(self): def t(*args): pass self.command_manager.register_command('t', t) called = self.command_manager.is_command('t', True) self.assertTrue(called) not_called = self.command_manager.is_command('f', True) self.assertFalse(not_called) # FIXME: not sure what actually want here called_w_args = self.command_manager.is_command( 't these are args', True) self.assertTrue(called_w_args) def test_get_callback_recursively_none(self): result = self.command_manager._get_callback_recursively(None) self.assertEqual(len(result), 3) for r in result: self.assertIsNone(r) def test_cmd_commands(self): def t(): pass self.command_manager.register_command('test', t) nested = {'test': t} self.command_manager.register_command('nested', nested) commands = self.command_manager._cmd_commands(None) self.assertIn('test', commands) self.assertIn('nested test', commands) self.assertNotIn('blah', commands) # TODO: test `help` and `commands`? self.assertEqual(len(commands), 4)
class Shell(cmd.Cmd): def __init__(self, context=None, prompt_name='vexbot', publish_address=None, subscribe_address=None, **kwargs): super().__init__() self.messaging = ZmqMessaging('shell', publish_address, subscribe_address, 'shell') self.command_manager = CommandManager(self.messaging) # FIXME self.command_manager._commands.pop('commands') self.stdout.write('Vexbot {}\n'.format(__version__)) if kwargs.get('already_running', False): self.stdout.write('vexbot already running\n') self.stdout.write("Type \"help\" for command line help or " "\"commands\" for bot commands\n\n") self.command_manager.register_command('start_vexbot', _start_vexbot) self.messaging.start_messaging() self.prompt = prompt_name + ': ' self.misc_header = "Commands" self._exit_loop = False self._set_readline_helper(kwargs.get('history_file')) def default(self, arg): if not self.command_manager.is_command(arg, call_command=True): command, argument, line = self.parseline(arg) self.messaging.send_command(command=command, args=argument, line=line) def _set_readline_helper(self, history_file=None): try: import readline except ImportError: return try: readline.read_history_file(history_file) except IOError: pass readline.set_history_length(1000) atexit.register(readline.write_history_file, history_file) def run(self): frame = None while True and not self._exit_loop: try: # NOTE: not blocking here to check the _exit_loop condition frame = self.messaging.sub_socket.recv_multipart(zmq.NOBLOCK) except zmq.error.ZMQError: pass sleep(.5) if frame: message = decode_vex_message(frame) if message.type == 'RSP': self.stdout.write("\n{}\n".format(self.doc_leader)) header = message.contents.get('original', 'Response') contents = message.contents.get('response', None) # FIXME if (isinstance(header, (tuple, list)) and isinstance(contents, (tuple, list)) and contents): for head, content in zip(header, contents): self.print_topics(head, (contents, ), 15, 70) else: if isinstance(contents, str): contents = (contents, ) self.print_topics(header, contents, 15, 70) self.stdout.write("vexbot: ") self.stdout.flush() else: # FIXME print(message.type, message.contents, 'fix me in shell adapter, run function') frame = None def _create_command_function(self, command): def resulting_function(arg): self.default(' '.join((command, arg))) return resulting_function def do_EOF(self, arg): self.stdout.write('\n') # NOTE: This ensures we exit out of the `run` method on EOF self._exit_loop = True return True def get_names(self): return dir(self) def do_help(self, arg): if arg: if self.command_manager.is_command(arg): doc = self.command_manager._commands[arg].__doc__ if doc: self.stdout.write("{}\n".format(str(doc))) else: self.messaging.send_command(command='help', args=arg) else: self.stdout.write("{}\n".format(self.doc_leader)) # TODO: get these from robot? self.print_topics(self.misc_header, [ 'start vexbot\nhelp [foo]', ], 15, 80) def add_completion(self, command): setattr(self, 'do_{}'.format(command), self._create_command_function(command)) """
class Shell(cmd.Cmd): def __init__(self, context=None, prompt_name='vexbot', publish_address=None, subscribe_address=None, **kwargs): super().__init__() self.messaging = ZmqMessaging('shell', publish_address, subscribe_address, 'shell') self.command_manager = CommandManager(self.messaging) # FIXME self.command_manager._commands.pop('commands') self.stdout.write('Vexbot {}\n'.format(__version__)) if kwargs.get('already_running', False): self.stdout.write('vexbot already running\n') self.stdout.write("Type \"help\" for command line help or " "\"commands\" for bot commands\n\n") self.command_manager.register_command('start_vexbot', _start_vexbot) self.messaging.start_messaging() self.prompt = prompt_name + ': ' self.misc_header = "Commands" self._exit_loop = False self._set_readline_helper(kwargs.get('history_file')) def default(self, arg): if not self.command_manager.is_command(arg, call_command=True): command, argument, line = self.parseline(arg) self.messaging.send_command(command=command, args=argument, line=line) def _set_readline_helper(self, history_file=None): try: import readline except ImportError: return try: readline.read_history_file(history_file) except IOError: pass readline.set_history_length(1000) atexit.register(readline.write_history_file, history_file) def run(self): frame = None while True and not self._exit_loop: try: # NOTE: not blocking here to check the _exit_loop condition frame = self.messaging.sub_socket.recv_multipart(zmq.NOBLOCK) except zmq.error.ZMQError: pass sleep(.5) if frame: message = decode_vex_message(frame) if message.type == 'RSP': self.stdout.write("\n{}\n".format(self.doc_leader)) header = message.contents.get('original', 'Response') contents = message.contents.get('response', None) # FIXME if (isinstance(header, (tuple, list)) and isinstance(contents, (tuple, list)) and contents): for head, content in zip(header, contents): self.print_topics(head, (contents,), 15, 70) else: if isinstance(contents, str): contents = (contents,) self.print_topics(header, contents, 15, 70) self.stdout.write("vexbot: ") self.stdout.flush() else: # FIXME print(message.type, message.contents, 'fix me in shell adapter, run function') frame = None def _create_command_function(self, command): def resulting_function(arg): self.default(' '.join((command, arg))) return resulting_function def do_EOF(self, arg): self.stdout.write('\n') # NOTE: This ensures we exit out of the `run` method on EOF self._exit_loop = True return True def get_names(self): return dir(self) def do_help(self, arg): if arg: if self.command_manager.is_command(arg): doc = self.command_manager._commands[arg].__doc__ if doc: self.stdout.write("{}\n".format(str(doc))) else: self.messaging.send_command(command='help', args=arg) else: self.stdout.write("{}\n".format(self.doc_leader)) # TODO: get these from robot? self.print_topics(self.misc_header, ['start vexbot\nhelp [foo]', ], 15, 80) def add_completion(self, command): setattr(self, 'do_{}'.format(command), self._create_command_function(command)) """