def setUp(self): def run_sync(self_, A, B): assert isinstance(self_, _CommandBase) self.div_result = A / B return True async def run_async(self_, A, B): assert isinstance(self_, _CommandBase) await asyncio.sleep(0, loop=self_.loop) self.div_result = A / B return True argspecs = ({ 'names': ('A', ), 'type': int, 'description': 'First number' }, { 'names': ('B', ), 'type': int, 'description': 'Second number' }) self.div_sync = make_cmdcls(name='div', run=run_sync, argspecs=argspecs, provides=('sync', )) self.div_async = make_cmdcls(name='div', run=run_async, argspecs=argspecs, provides=('async', )) self.div_result = None self.cb_success = Callback() self.cb_error = Callback()
def setUp(self): self.cmdmgr = CommandManager() self.cmd_foo = make_cmdcls(name='foo', provides=('cli',)) self.cmd_bar = make_cmdcls(name='bar', provides=('tui',)) self.cmd_baz = make_cmdcls(name='baz', provides=('cli', 'tui')) for c in (self.cmd_foo, self.cmd_bar, self.cmd_baz): self.cmdmgr.register(c)
def setUp(self): def run_sync(self_, A, B): assert isinstance(self_, _CommandBase) self_.info(round(int(A) / int(B))) async def run_async(self_, A, B): assert isinstance(self_, _CommandBase) await asyncio.sleep(0) self_.info(round(int(A) / int(B))) argspecs = ({ 'names': ('A', ), 'type': int, 'description': 'First number' }, { 'names': ('B', ), 'type': int, 'description': 'Second number' }) self.div_sync = make_cmdcls(name='div', run=run_sync, argspecs=argspecs, provides=('sync', )) self.div_async = make_cmdcls(name='div', run=run_async, argspecs=argspecs, provides=('async', )) self.info_handler = Callback() self.error_handler = Callback()
def setUp(self): # It's ok to use the default loop here because we're not using it in # this test class. self.cmdmgr = CommandManager(loop=asyncio.get_event_loop()) self.cmd_foo = make_cmdcls(name='foo', provides=('cli',)) self.cmd_bar = make_cmdcls(name='bar', provides=('tui',)) self.cmd_baz = make_cmdcls(name='baz', provides=('cli', 'tui')) for c in (self.cmd_foo, self.cmd_bar, self.cmd_baz): self.cmdmgr.register(c)
def setUp(self): self.cmdmgr = CommandManager() self.cmdmgr.register(make_cmdcls(name='dotui', provides=('tui', ))) self.cmdmgr.register(make_cmdcls(name='docli', provides=('cli', ))) self.cmdmgr.register( make_cmdcls(name='doboth', provides=('cli', 'tui'))) self.cmdmgr.register( make_cmdcls(name='dotorrent', provides=('cli', 'tui'), category='torrent'))
def setUp(self): super().setUp() self.true_cb = Callback() self.false_cb = Callback() def true_run(self_, *args, **kwargs): self.true_cb(*args, **kwargs) ; return True def false_run(self_, *args, **kwargs): self.false_cb(*args, **kwargs) ; raise CmdError('Nope') args = ({'names': ('-a',), 'action': 'store_true', 'description': 'A args'}, {'names': ('-b',), 'action': 'store_true', 'description': 'B args'}, {'names': ('-c',), 'action': 'store_true', 'description': 'C args'}) true_cmd = make_cmdcls(name='true', run=true_run, argspecs=args, provides=('T',)) false_cmd = make_cmdcls(name='false', run=false_run, argspecs=args, provides=('F',)) self.cmdmgr.register(true_cmd) self.cmdmgr.register(false_cmd)
def test_mandatory_properties(self): attrs = {'name': 'foo', 'run': lambda self: None, 'category': 'catfoo', 'provides': ('tui', 'cli'), 'description': 'This command is the foo!'} for missing_attr in ('name', 'category', 'provides', 'description', 'run'): this_attrs = attrs.copy() del this_attrs[missing_attr] with self.assertRaises(RuntimeError) as cm: make_cmdcls(**this_attrs, defaults=False) self.assertIn(missing_attr, str(cm.exception)) self.assertIn('attribute', str(cm.exception).lower()) # assertRaisesNot make_cmdcls(**attrs, defaults=False)
def test_get_cmdcls(self): self.cmdmgr.active_interface = 'cli' self.assertEqual(self.cmdmgr.get_cmdcls('bar', interface='ACTIVE', exclusive=False), None) # bar is 'tui' command self.assertEqual(self.cmdmgr.get_cmdcls('bar', interface='ANY', exclusive=False), self.cmd_bar) self.assertEqual(self.cmdmgr.get_cmdcls('baz', interface='cli', exclusive=True), None) # baz supports cli but not exclusively # Add another 'foo' command for 'tui' (the first one for 'cli' is added in setUp) cmd_foo_tui = make_cmdcls(name='foo', provides=('tui',)) self.cmdmgr.register(cmd_foo_tui) self.assertEqual(self.cmdmgr.get_cmdcls('foo', interface='ACTIVE', exclusive=False), self.cmd_foo) self.cmdmgr.active_interface = 'tui' self.assertEqual(self.cmdmgr.get_cmdcls('foo', interface='ACTIVE', exclusive=False), cmd_foo_tui) # Both commands support their interfaces exclusively self.assertEqual(self.cmdmgr.get_cmdcls('foo', interface='cli', exclusive=True), self.cmd_foo) self.assertEqual(self.cmdmgr.get_cmdcls('foo', interface='tui', exclusive=True), cmd_foo_tui) with self.assertRaises(ValueError) as cm: self.cmdmgr.get_cmdcls('foo', interface='brain') self.assertIn('brain', str(cm.exception)) self.assertIn('interface', str(cm.exception).lower())
def test_command_requests_unknown_resource(self): resource = [50, 93, -11] self.cmdmgr.resources['numberwang'] = resource self.cmdmgr.register(make_cmdcls(name='foo', badgerwang=ExpectedResource)) foo = self.cmdmgr.get_cmdcls('foo', interface='ANY') with self.assertRaises(AttributeError) as cm: foo().badgerwang self.assertIn('badgerwang', str(cm.exception)) self.assertIn('resource', str(cm.exception).lower())
def test_argparser(self): argspecs = ({'names': ('ARG1',), 'description': 'First arg'}, {'names': ('ARG2',), 'description': 'Second arg'}) cmdcls = make_cmdcls(argspecs=argspecs) self.assertTrue(hasattr(cmdcls, '_argparser')) kwargs = vars(cmdcls._argparser.parse_args(['foo', 'bar'])) self.assertEqual(kwargs, {'ARG1': 'foo', 'ARG2': 'bar'}) with self.assertRaises(CmdArgError): cmdcls._argparser.parse_args(['foo', 'bar', 'baz'])
def setUp(self): super().setUp() self.mock_gui = asynctest.mock.MagicMock() argspecs = ({'names': ('A',), 'type': int, 'description': 'First number'}, {'names': ('B',), 'type': int, 'description': 'Second number'}) def run_add(self_, A, B, _gui=self.mock_gui): print('add called with %r, %r' % (A, B)) _gui.display('Result: %d' % (int(A) + int(B),)) self.cmdmgr.register(make_cmdcls(name='add', run=run_add, argspecs=argspecs, provides=('gui',))) async def run_sub(self_, A, B, _gui=self.mock_gui): print('sub called with %r, %r' % (A, B)) _gui.display('Result: %d' % (int(A) - int(B),)) await asyncio.sleep(0) self.cmdmgr.register(make_cmdcls(name='sub', run=run_sub, argspecs=argspecs, provides=('tui',)))
def test_kwargs_are_forwarded_to_cmd_instance(self): kwargs = {'foo': 'bar', 'one': 1} def run(self_cmd): for k,v in kwargs.items(): self.assertEqual(getattr(self_cmd, k), v) cmdcls = make_cmdcls(name='kwargs-test', run=run, provides=('sync',)) self.cmdmgr.register(cmdcls) self.cmdmgr.active_interface = 'sync' success = self.cmdmgr.run_sync('kwargs-test', **kwargs) self.assertEqual(success, True)
def test_commands_get_only_expected_resources(self): resource = [50, 93, -11] self.cmdmgr.resources['numberwang'] = resource div_sync = self.cmdmgr.get_cmdcls('div', interface='sync') div_async = self.cmdmgr.get_cmdcls('div', interface='sync') self.assertFalse(hasattr(div_sync, 'numberwang')) self.assertFalse(hasattr(div_async, 'numberwang')) self.cmdmgr.register(make_cmdcls(name='foo', numberwang=ExpectedResource)) foo = self.cmdmgr.get_cmdcls('foo', interface='ANY') self.assertTrue(hasattr(foo, 'numberwang')) self.assertEqual(foo().numberwang, resource)
def test_expected_resource_available_in_run_method(self): argspecs = ({'names': ('A',), 'description': 'First number'}, {'names': ('B',), 'description': 'Second number'}) result = None def run(self, A, B): nonlocal result result = self.template.format(number=int(int(A)/int(B))) return True cmdcls = make_cmdcls(run=run, argspecs=argspecs, template=ExpectedResource) cmdcls.template = 'Result: {number}' process = cmdcls(['100', '50']) self.assertEqual(process.success, True) self.assertEqual(result, 'Result: 2')
def setUp(self): self.cmdmgr = CommandManager(loop=self.loop) def sync_run(self_, A, B): assert isinstance(self_, _CommandBase) self.div_result = A / B return True async def async_run(self_, A, B): assert isinstance(self_, _CommandBase) await asyncio.sleep(0, loop=self_.loop) self.div_result = A / B return True argspecs = ({'names': ('A',), 'type': int, 'description': 'First number'}, {'names': ('B',), 'type': int, 'description': 'Second number'}) self.cmdmgr.register( make_cmdcls(name='div', run=sync_run, argspecs=argspecs, provides=('sync',)) ) self.cmdmgr.register( make_cmdcls(name='div', run=async_run, argspecs=argspecs, provides=('async',)) ) async def async_run_CmdError(self_, msg): await asyncio.sleep(0, loop=self_.loop) raise CmdError(msg) def sync_run_CmdError(self_, msg): raise CmdError(msg) argspecs = ({'names': ('msg',), 'type': str, 'description': 'Error message'},) self.cmdmgr.register( make_cmdcls(name='error', run=async_run_CmdError, argspecs=argspecs, provides=('async',)) ) self.cmdmgr.register( make_cmdcls(name='error', run=sync_run_CmdError, argspecs=argspecs, provides=('sync',)) ) async def async_run_Exception(self_): await asyncio.sleep(0, loop=self_.loop) 1/0 def sync_run_Exception(self_): 1/0 self.cmdmgr.register( make_cmdcls(name='raise', run=async_run_Exception, argspecs=(), provides=('async',)) ) self.cmdmgr.register( make_cmdcls(name='raise', run=sync_run_Exception, argspecs=(), provides=('sync',)) ) self.cb_error = Callback() self.cb_success = Callback()
def setUp(self): self.info_handler = Callback() self.error_handler = Callback() self.cmdmgr = CommandManager(loop=self.loop, info_handler=self.info_handler, error_handler=self.error_handler) def run_sync(self_, A, B): assert isinstance(self_, _CommandBase) self_.info(round(int(A) / int(B))) async def run_async(self_, A, B): assert isinstance(self_, _CommandBase) await asyncio.sleep(0, loop=self_.loop) self_.info(round(int(A) / int(B))) argspecs = ({'names': ('A',), 'type': int, 'description': 'First number'}, {'names': ('B',), 'type': int, 'description': 'Second number'}) self.cmdmgr.register( make_cmdcls(name='div', run=run_sync, argspecs=argspecs, provides=('sync',)) ) self.cmdmgr.register( make_cmdcls(name='div', run=run_async, argspecs=argspecs, provides=('async',)) ) def run_sync_CmdError(self_, msg): raise CmdError(msg) async def run_async_CmdError(self_, msg): await asyncio.sleep(0, loop=self_.loop) raise CmdError(msg) argspecs = ({'names': ('msg',), 'description': 'Error message'},) self.cmdmgr.register( make_cmdcls(name='error', run=run_sync_CmdError, argspecs=argspecs, provides=('sync',)) ) self.cmdmgr.register( make_cmdcls(name='error', run=run_async_CmdError, argspecs=argspecs, provides=('async',)) ) def run_sync_Exception(self_): 1/0 async def run_async_Exception(self_): await asyncio.sleep(0, loop=self_.loop) 1/0 self.cmdmgr.register( make_cmdcls(name='raise', run=run_sync_Exception, argspecs=(), provides=('sync',)) ) self.cmdmgr.register( make_cmdcls(name='raise', run=run_async_Exception, argspecs=(), provides=('async',)) )
def test_names_and_aliases(self): cmdcls = make_cmdcls(name='foo', aliases=('bar', 'baz')) self.assertEqual(cmdcls.names, ['foo', 'bar', 'baz']) cmdcls = make_cmdcls(name='foo') self.assertEqual(cmdcls.names, ['foo'])
def test_kwargs_become_instance_attributes(self): cmdcls = make_cmdcls() cmdinst = cmdcls(foo='bar', one=1) self.assertEqual(cmdinst.foo, 'bar') self.assertEqual(cmdinst.one, 1)
def test_adding_resources_to_new_commands(self): resource = tuple(range(10)) self.cmdmgr.resources['numbers'] = resource self.cmdmgr.register(make_cmdcls(name='foo', numbers=ExpectedResource)) foo = self.cmdmgr.get_cmdcls('foo', interface='ANY') self.assertEqual(foo.numbers, resource)
def test_missing_expected_resource_error(self): cmdcls = make_cmdcls(api=ExpectedResource) with self.assertRaises(AttributeError) as cm: cmdcls().api self.assertIn('api', str(cm.exception)) self.assertIn('resource', str(cm.exception).lower())