class TestCommandManagerChainedCalls(TestCommandManagerCallsBase): def setUp(self): super().setUp() self.true_cb = Callback() self.false_cb = Callback() def true_run(self_, *args, **kwargs): assert args is () self.true_cb(**kwargs) def false_run(self_, *args, **kwargs): assert args is () self.false_cb(**kwargs) raise CmdError() 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) async def assert_success(self, cmdchain): success = self.cmdmgr.run_sync(cmdchain) self.assertEqual(success, True) success = await self.cmdmgr.run_async(cmdchain) self.assertEqual(success, True) async def assert_failure(self, cmdchain, infos=(), errors=()): success = self.cmdmgr.run_sync(cmdchain) self.assertEqual(success, False) if infos: self.assertEqual(self.info_handler.args, list(infos)) if errors: self.assertEqual(self.error_handler.args, list(errors)) self.info_handler.reset() self.error_handler.reset() success = await self.cmdmgr.run_async(cmdchain) self.assertEqual(success, False) if infos: self.assertEqual(self.info_handler.args, list(infos)) if errors: self.assertEqual(self.error_handler.args, list(errors)) async def test_cmdchain_formats(self): await self.assert_success('true ; true') await self.assert_failure('true ; false') await self.assert_success([['true'], ';', ['true']]) await self.assert_failure([['true'], ';', ['false']]) async def test_empty_cmdchain(self): await self.assert_success('') await self.assert_success([]) await self.assert_success([[], []]) async def test_valid_cmdchain(self): await self.assert_success([['false'], ';', ['true']]) await self.assert_success([['false'], ['true']]) await self.assert_success((['true'], '&', ['true'])) await self.assert_success([['false'], '|', ('true',)]) await self.assert_failure([('true',), ';', ['false']]) await self.assert_failure([('true',), ('false',)]) await self.assert_failure((('true',), '&', ('false',))) await self.assert_failure([['false'], '|', ['false']]) async def test_trailing_operator(self): await self.assert_failure('true ; false &') await self.assert_success([('false',), ';', ('true',), '|']) async def run_testcases(self, testcases, checkfunc): # Run each test in list format and in string format for cmdchain, kwargs in testcases: await checkfunc(cmdchain, **kwargs) cmdchain_str = ' '.join(cmd if isinstance(cmd, str) else ' '.join(cmd) for cmd in cmdchain) await checkfunc(cmdchain_str, **kwargs) async def test_consecutive_operators(self): async def assert_consecutive_ops(cmdchain, op1, op2): self.error_handler.reset() self.cmdmgr.run_sync(cmdchain) self.assertEqual(self.error_handler.args, [('Consecutive operators: %s %s' % (op1, op2),)]) self.error_handler.reset() await self.cmdmgr.run_async(cmdchain) self.assertEqual(self.error_handler.args, [('Consecutive operators: %s %s' % (op1, op2),)]) testcases = ( ([['true'], ';', ';', ['false']], {'op1': ';', 'op2': ';'}), ([['true'], '&', '&', ['false']], {'op1': '&', 'op2': '&'}), ([['false'], '|', '|', ['true']], {'op1': '|', 'op2': '|'}), ([['true'], ';', '&', ['false']], {'op1': ';', 'op2': '&'}), ([['true'], '&', '|', ['false']], {'op1': '&', 'op2': '|'}), ([['false'], '|', ';', ['true']], {'op1': '|', 'op2': ';'}), ([['false'], ';', '|', ['false']], {'op1': ';', 'op2': '|'}), ) await self.run_testcases(testcases, assert_consecutive_ops) async def test_final_process_determines_overall_success(self): async def do_test(cmdchain, success): result = self.cmdmgr.run_sync(cmdchain) self.assertEqual(result, success) result = await self.cmdmgr.run_async(cmdchain) self.assertEqual(result, success) testcases = ( ([['true'], ';', ['true']], {'success': True}), ([['false'], ';', ['true']], {'success': True}), ([['true'], ';', ['false']], {'success': False}), ([['false'], ';', ['false']], {'success': False}), ([['true'], '&', ['true']], {'success': True}), ([['false'], '&', ['true']], {'success': False}), ([['true'], '&', ['false']], {'success': False}), ([['false'], '&', ['false']], {'success': False}), ([['true'], '|', ['true']], {'success': True}), ([['false'], '|', ['true']], {'success': True}), ([['true'], '|', ['false']], {'success': True}), ([['false'], '|', ['false']], {'success': False}), ) await self.run_testcases(testcases, do_test) async def test_nonexisting_cmd_in_cmdchain(self): async def do_test(cmdchain, success, true_calls=0, false_calls=0, errors=()): self.error_handler.reset() ; self.true_cb.reset() ; self.false_cb.reset() result = self.cmdmgr.run_sync(cmdchain) self.assertEqual(result, success) self.assertEqual(self.true_cb.calls, true_calls) self.assertEqual(self.false_cb.calls, false_calls) self.assertEqual(self.error_handler.args, list(errors)) self.error_handler.reset() ; self.true_cb.reset() ; self.false_cb.reset() result = await self.cmdmgr.run_async(cmdchain) self.assertEqual(result, success) self.assertEqual(self.true_cb.calls, true_calls) self.assertEqual(self.false_cb.calls, false_calls) self.assertEqual(self.error_handler.args, list(errors)) testcases = ( ([['true'], ';', ['foo'], ';', ['false']], {'success': False, 'true_calls': 1, 'false_calls': 1, 'errors': [('foo: Unknown command',)]}), ([['true'], '|', ['foo'], '|', ['false']], {'success': True, 'true_calls': 1, 'false_calls': 0}), ([['true'], '&', ['foo'], '&', ['false']], {'success': False, 'true_calls': 1, 'false_calls': 0, 'errors': [('foo: Unknown command',)]}), ([['true'], '&', ['foo'], '|', ['false']], {'success': False, 'true_calls': 1, 'false_calls': 1, 'errors': [('foo: Unknown command',)]}), ([['true'], '&', ['foo'], '|', ['true']], {'success': True, 'true_calls': 2, 'false_calls': 0, 'errors': [('foo: Unknown command',)]}), ([['false'], '|', ['foo'], '&', ['true']], {'success': False, 'true_calls': 0, 'false_calls': 1, 'errors': [('foo: Unknown command',)]}), ([['false'], '&', ['foo'], '&', ['true']], {'success': False, 'true_calls': 0, 'false_calls': 1}), ([['false'], '|', ['foo'], '|', ['true']], {'success': True, 'true_calls': 1, 'false_calls': 1, 'errors': [('foo: Unknown command',)]}), ) await self.run_testcases(testcases, do_test) async def test_cmd_from_inactive_interface_in_cmdchain(self): async def do_test(cmdchain, success, true_calls=0, false_calls=0, errors=()): self.error_handler.reset() ; self.true_cb.reset() ; self.false_cb.reset() result = self.cmdmgr.run_sync(cmdchain) self.assertEqual(result, success) self.assertEqual(self.true_cb.calls, true_calls) self.assertEqual(self.false_cb.calls, false_calls) self.assertEqual(self.error_handler.args, list(errors)) self.error_handler.reset() ; self.true_cb.reset() ; self.false_cb.reset() result = await self.cmdmgr.run_async(cmdchain) self.assertEqual(result, success) self.assertEqual(self.true_cb.calls, true_calls) self.assertEqual(self.false_cb.calls, false_calls) self.assertEqual(self.error_handler.args, list(errors)) # Calls to 'false' are ignored and evaluate to True in the command chain self.cmdmgr.active_interface = 'T' testcases = ( [[['true'], ';', ['false']], {'success': True, 'true_calls': 1, 'false_calls': 0}], [[['false'], ';', ['true']], {'success': True, 'true_calls': 1, 'false_calls': 0}], [[['true'], '&', ['false']], {'success': True, 'true_calls': 1, 'false_calls': 0}], [[['false'], '&', ['true']], {'success': True, 'true_calls': 1, 'false_calls': 0}], [[['true'], '|', ['false']], {'success': True, 'true_calls': 1, 'false_calls': 0}], [[['false'], '|', ['true']], {'success': True, 'true_calls': 0, 'false_calls': 0}], ) await self.run_testcases(testcases, do_test) # Calls to 'false' are ignored and evaluate to True in the command chain self.cmdmgr.active_interface = 'F' testcases = ( [[['true'], ';', ['false']], {'success': False, 'true_calls': 0, 'false_calls': 1}], [[['false'], ';', ['true']], {'success': True, 'true_calls': 0, 'false_calls': 1}], [[['true'], '&', ['false']], {'success': False, 'true_calls': 0, 'false_calls': 1}], [[['false'], '&', ['true']], {'success': False, 'true_calls': 0, 'false_calls': 1}], [[['true'], '|', ['false']], {'success': True, 'true_calls': 0, 'false_calls': 0}], [[['false'], '|', ['true']], {'success': True, 'true_calls': 0, 'false_calls': 1}], ) await self.run_testcases(testcases, do_test) async def test_cmdchain_with_arguments(self): async def do_test(cmdchain, success, true_args=(), false_args=(), errors=()): self.error_handler.reset() ; self.true_cb.reset() ; self.false_cb.reset() result = self.cmdmgr.run_sync(cmdchain) self.assertEqual(result, success) self.assertEqual(self.true_cb.kwargs, list(true_args)) self.assertEqual(self.false_cb.kwargs, list(false_args)) self.assertEqual(self.error_handler.args, list(errors)) self.error_handler.reset() ; self.true_cb.reset() ; self.false_cb.reset() result = await self.cmdmgr.run_async(cmdchain) self.assertEqual(result, success) self.assertEqual(self.true_cb.kwargs, list(true_args)) self.assertEqual(self.false_cb.kwargs, list(false_args)) self.assertEqual(self.error_handler.args, list(errors)) testcases = ( ([['true', '-a'], '&', ['true', '-a', '-b'], '&', ['true', '-a', '-b', '-c']], {'success': True, 'true_args': [{'a': True, 'b': False, 'c': False}, {'a': True, 'b': True, 'c': False}, {'a': True, 'b': True, 'c': True}]}), ([['true', '-a'], '&', ['true', '-a', '-b'], '|', ['true', '-a', '-b', '-c']], {'success': True, 'true_args': [{'a': True, 'b': False, 'c': False}, {'a': True, 'b': True, 'c': False}]}), ([['true', '-a'], '|', ['true', '-a', '-b'], '|', ['true', '-a', '-b', '-c']], {'success': True, 'true_args': [{'a': True, 'b': False, 'c': False}]}), ([['false', '-a'], '|', ['false', '-a', '-b'], '|', ['false', '-a', '-b', '-c']], {'success': False, 'false_args': [{'a': True, 'b': False, 'c': False}, {'a': True, 'b': True, 'c': False}, {'a': True, 'b': True, 'c': True}]}), ([['false', '-a'], '|', ['false', '-a', '-b'], '&', ['false', '-a', '-b', '-c']], {'success': False, 'false_args': [{'a': True, 'b': False, 'c': False}, {'a': True, 'b': True, 'c': False}]}), ([['false', '-a'], '&', ['false', '-a', '-b'], '&', ['false', '-a', '-b', '-c']], {'success': False, 'false_args': [{'a': True, 'b': False, 'c': False}]}), ([['false', '-a'], ';', ['true', '-a', '-b', '-x'], ';', ['true', '-a', '-b', '-c']], {'success': True, 'false_args': [{'a': True, 'b': False, 'c': False}], 'true_args': [{'a': True, 'b': True, 'c': True}], 'errors': [('true: Unrecognized arguments: -x',)]}), ) await self.run_testcases(testcases, do_test)
class TestCommandBase(asynctest.TestCase): 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 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_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_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 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_argparser_error(self): process = self.div_sync(['10', '2', '--frobnicate'], info_handler=self.info_handler, error_handler=self.error_handler) self.assertEqual(process.finished, True) self.assertEqual(process.success, False) self.assertEqual(self.info_handler.calls, 0) self.assertEqual(self.error_handler.calls, 1) self.assertEqual(str(self.error_handler.args[0][0]), 'div: Unrecognized arguments: --frobnicate') def check(self, process, success, infos=(), errors=()): self.assertEqual(process.finished, True) self.assertEqual(process.success, success) self.assertEqual(self.error_handler.args, list(errors)) self.assertEqual(self.info_handler.args, list(infos)) # Test running commands with stopped asyncio loop def test_run_does_not_raise_exception_in_sync_context(self): process = self.div_sync(['10', '2'], info_handler=self.info_handler, error_handler=self.error_handler) self.check(process, success=True, infos=[('div: 5', )]) self.info_handler.reset() self.error_handler.reset() process = self.div_async(['50', '2'], info_handler=self.info_handler, error_handler=self.error_handler) process.wait_sync() self.check(process, success=True, infos=[('div: 25', )]) def test_run_raises_CmdError_in_sync_context(self): process = self.div_sync(['10', 'foo'], info_handler=self.info_handler, error_handler=self.error_handler) self.check(process, success=False, errors=[("div: Argument B: invalid int value: 'foo'", )]) self.info_handler.reset() self.error_handler.reset() process = self.div_async(['1', 'bar'], info_handler=self.info_handler, error_handler=self.error_handler) process.wait_sync() self.check(process, success=False, errors=[("div: Argument B: invalid int value: 'bar'", )]) def test_run_raises_Exception_in_sync_context(self): with self.assertRaises(ZeroDivisionError): self.div_sync(['10', '0'], info_handler=self.info_handler, error_handler=self.error_handler) self.assertEqual(self.info_handler.args, []) self.assertEqual(self.error_handler.args, []) self.info_handler.reset() self.error_handler.reset() process = self.div_async(['1', '0'], info_handler=self.info_handler, error_handler=self.error_handler) with self.assertRaises(ZeroDivisionError): process.wait_sync() self.assertEqual(self.info_handler.args, []) self.assertEqual(self.error_handler.args, []) # Test running commands with running asyncio loop async def test_run_does_not_raise_exception_in_async_context(self): process = self.div_sync(['10', '2'], info_handler=self.info_handler, error_handler=self.error_handler) self.check(process, success=True, infos=[('div: 5', )]) self.info_handler.reset() self.error_handler.reset() process = self.div_async(['10', '5'], info_handler=self.info_handler, error_handler=self.error_handler) await process.wait_async() self.check(process, success=True, infos=[('div: 2', )]) async def test_run_raises_CmdError_in_async_context(self): process = self.div_sync(['10', 'foo'], info_handler=self.info_handler, error_handler=self.error_handler) self.check(process, success=False, errors=[("div: Argument B: invalid int value: 'foo'", )]) self.info_handler.reset() self.error_handler.reset() process = self.div_async(['100', 'bar'], info_handler=self.info_handler, error_handler=self.error_handler) await process.wait_async() self.check(process, success=False, errors=[("div: Argument B: invalid int value: 'bar'", )]) async def test_run_raises_Exception_in_async_context(self): with self.assertRaises(ZeroDivisionError): self.div_sync(['10', '0'], info_handler=self.info_handler, error_handler=self.error_handler) self.assertEqual(self.info_handler.calls, 0) self.assertEqual(self.error_handler.calls, 0)
class TestCommandManagerChainedCalls(TestCommandManagerCallsBase): 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 assert_success(self, cmdchain): success = self.cmdmgr.run_sync(cmdchain, on_success=self.cb_success, on_error=self.cb_error) self.assertEqual(success, True) def assert_failure(self, cmdchain): success = self.cmdmgr.run_sync(cmdchain, on_success=self.cb_success, on_error=self.cb_error) self.assertEqual(success, False) @asynctest.ignore_loop def test_empty_cmdchain(self): self.assert_success([]) self.assert_success('') @asynctest.ignore_loop def test_run_good_parsed_cmdchain(self): self.assert_success([['false'], ';', ('true', )]) self.assert_success([['false'], ['true']]) self.assert_success((('true', ), '&', ['true'])) self.assert_success(iter([['false'], '|', ['true']])) self.assert_failure([['true'], ';', ('false', )]) self.assert_failure([['true'], ['false']]) self.assert_failure((['true'], '&', ['false'])) self.assert_failure((['false'], '|', ['false'])) def assert_invalid_cmdchain_format(self, cmdchain): with self.assertRaises(RuntimeError): self.cmdmgr.run_sync(cmdchain) @asynctest.ignore_loop def test_run_bad_parsed_cmdchain(self): self.assert_invalid_cmdchain_format([['true'], ';', 'true']) self.assert_invalid_cmdchain_format((('true', ), '&', iter(['true']))) self.assert_invalid_cmdchain_format((('true', ), '&&&', ['true'])) @asynctest.ignore_loop def test_consecutive_operators(self): def assert_consecutive_ops(cmdchain, op1, op2): with self.assertRaises(CmdError) as cm: self.cmdmgr.run_sync(cmdchain) self.assertIn('Consecutive operators', str(cm.exception)) self.assertIn('%s %s' % (op1, op2), str(cm.exception)) assert_consecutive_ops('true ; ; true', ';', ';') assert_consecutive_ops('true ; & true', ';', '&') assert_consecutive_ops('true & | true', '&', '|') assert_consecutive_ops([['true'], '&', '|', ['true']], '&', '|') @asynctest.ignore_loop def test_nonexisting_cmd_in_cmdchain(self): def do_test(cmdchain, success, success_calls, error_calls, true_calls, false_calls, true_args, false_args): succ = self.cmdmgr.run_sync(cmdchain, on_success=self.cb_success, on_error=self.cb_error) self.assertEqual(succ, success) self.assertEqual(self.cb_success.calls, success_calls) self.assertEqual(self.cb_error.calls, error_calls) self.assertEqual(self.true_cb.calls, true_calls) self.assertEqual(self.false_cb.calls, false_calls) self.assertEqual(self.true_cb.kwargs, true_args) self.assertEqual(self.false_cb.kwargs, false_args) self.cb_success.reset() self.cb_error.reset() self.true_cb.reset() self.false_cb.reset() do_test('true ; foo', False, 1, 1, 1, 0, [{ 'a': False, 'b': False, 'c': False }], []) do_test('false ; foo', False, 0, 2, 0, 1, [], [{ 'a': False, 'b': False, 'c': False }]) do_test('false | foo', False, 0, 2, 0, 1, [], [{ 'a': False, 'b': False, 'c': False }]) do_test('false & foo', False, 0, 1, 0, 1, [], [{ 'a': False, 'b': False, 'c': False }]) do_test('true & foo', False, 1, 1, 1, 0, [{ 'a': False, 'b': False, 'c': False }], []) do_test('foo & true', False, 0, 1, 0, 0, [], []) do_test('foo | false', False, 0, 2, 0, 1, [], [{ 'a': False, 'b': False, 'c': False }]) do_test('foo ; true', True, 1, 1, 1, 0, [{ 'a': False, 'b': False, 'c': False }], []) @asynctest.ignore_loop def test_only_cmds_from_active_interface_are_called(self): def do_test(cmdchain, success, success_calls, error_calls, true_calls, false_calls, true_args, false_args): succ = self.cmdmgr.run_sync(cmdchain, on_success=self.cb_success, on_error=self.cb_error) self.assertEqual(succ, success) self.assertEqual(self.cb_success.calls, success_calls) self.assertEqual(self.cb_error.calls, error_calls) self.assertEqual(self.true_cb.calls, true_calls) self.assertEqual(self.false_cb.calls, false_calls) self.assertEqual(self.true_cb.kwargs, true_args) self.assertEqual(self.false_cb.kwargs, false_args) self.cb_success.reset() self.cb_error.reset() self.true_cb.reset() self.false_cb.reset() # Calls to 'false' are ignored and evaluate to False in the command chain self.cmdmgr.active_interface = 'T' do_test('true ; false', False, 1, 0, 1, 0, [{ 'a': False, 'b': False, 'c': False }], []) do_test('false ; true', True, 1, 0, 1, 0, [{ 'a': False, 'b': False, 'c': False }], []) do_test('true & false', False, 1, 0, 1, 0, [{ 'a': False, 'b': False, 'c': False }], []) do_test('false & true', False, 0, 0, 0, 0, [], []) do_test('true | false', True, 1, 0, 1, 0, [{ 'a': False, 'b': False, 'c': False }], []) do_test('false | true', True, 1, 0, 1, 0, [{ 'a': False, 'b': False, 'c': False }], []) # Calls to 'true' are ignored and evaluate to False in the command chain self.cmdmgr.active_interface = 'F' do_test('true ; false', False, 0, 1, 0, 1, [], [{ 'a': False, 'b': False, 'c': False }]) do_test('false ; true', False, 0, 1, 0, 1, [], [{ 'a': False, 'b': False, 'c': False }]) do_test('true & false', False, 0, 0, 0, 0, [], []) do_test('false & true', False, 0, 1, 0, 1, [], [{ 'a': False, 'b': False, 'c': False }]) do_test('true | false', False, 0, 1, 0, 1, [], [{ 'a': False, 'b': False, 'c': False }]) do_test('false | true', False, 0, 1, 0, 1, [], [{ 'a': False, 'b': False, 'c': False }]) @asynctest.ignore_loop def test_final_process_determines_overall_success(self): def do_test(cmdchain, success): result = self.cmdmgr.run_sync(cmdchain, on_success=self.cb_success, on_error=self.cb_error) self.assertEqual(result, success) do_test([['true'], ';', ['true']], success=True) do_test([['false'], ';', ['true']], success=True) do_test([['true'], ';', ['false']], success=False) do_test([['false'], ';', ['false']], success=False) do_test([['true'], '&', ['true']], success=True) do_test([['false'], '&', ['true']], success=False) do_test([['true'], '&', ['false']], success=False) do_test([['false'], '&', ['false']], success=False) do_test([['true'], '|', ['true']], success=True) do_test([['false'], '|', ['true']], success=True) do_test([['true'], '|', ['false']], success=True) do_test([['false'], '|', ['false']], success=False) @asynctest.ignore_loop def test_sync_complete_chain_with_AND_operator(self): result = self.cmdmgr.run_sync( 'true -a & true -a -b & true -a -b -c', on_success=self.cb_success, on_error=self.cb_error) self.confirm_complete_chain_with_AND_operator(result) async def test_async_complete_chain_with_AND_operator(self): result = await self.cmdmgr.run_async( 'true -a & true -a -b & true -a -b -c', on_success=self.cb_success, on_error=self.cb_error) self.confirm_complete_chain_with_AND_operator(result) def confirm_complete_chain_with_AND_operator(self, result): self.assertEqual(result, True) self.assertEqual(self.cb_success.calls, 3) self.assertEqual(self.cb_error.calls, 0) self.assertEqual(self.true_cb.calls, 3) self.assertEqual(self.true_cb.kwargs, [{ 'a': True, 'b': False, 'c': False }, { 'a': True, 'b': True, 'c': False }, { 'a': True, 'b': True, 'c': True }]) self.assertEqual(self.false_cb.calls, 0) @asynctest.ignore_loop def test_sync_broken_chain_with_AND_operator(self): result = self.cmdmgr.run_sync( 'true -a & false -a -b & true -a -b -c', on_success=self.cb_success, on_error=self.cb_error) self.confirm_broken_chain_with_AND_operator(result) async def test_async_broken_chain_with_AND_operator(self): result = await self.cmdmgr.run_async( 'true -a & false -a -b & true -a -b -c', on_success=self.cb_success, on_error=self.cb_error) self.confirm_broken_chain_with_AND_operator(result) def confirm_broken_chain_with_AND_operator(self, result): self.assertEqual(result, False) self.assertEqual(self.cb_success.calls, 1) self.assertEqual(self.cb_error.calls, 1) self.assertEqual(self.true_cb.calls, 1) self.assertEqual(self.true_cb.kwargs, [{ 'a': True, 'b': False, 'c': False }]) self.assertEqual(self.false_cb.calls, 1) self.assertEqual(self.false_cb.kwargs, [{ 'a': True, 'b': True, 'c': False }]) @asynctest.ignore_loop def test_sync_complete_chain_with_OR_operator(self): result = self.cmdmgr.run_sync( 'false -a | false -a -b | true -a -b -c', on_success=self.cb_success, on_error=self.cb_error) self.confirm_complete_chain_with_OR_operator(result) async def test_async_complete_chain_with_OR_operator(self): result = await self.cmdmgr.run_async( 'false -a | false -a -b | true -a -b -c', on_success=self.cb_success, on_error=self.cb_error) self.confirm_complete_chain_with_OR_operator(result) def confirm_complete_chain_with_OR_operator(self, result): self.assertEqual(result, True) self.assertEqual(self.cb_success.calls, 1) self.assertEqual(self.cb_error.calls, 2) self.assertEqual(self.false_cb.calls, 2) self.assertEqual(self.false_cb.kwargs, [{ 'a': True, 'b': False, 'c': False }, { 'a': True, 'b': True, 'c': False }]) self.assertEqual(self.true_cb.calls, 1) self.assertEqual(self.true_cb.kwargs, [{ 'a': True, 'b': True, 'c': True }]) @asynctest.ignore_loop def test_sync_broken_chain_with_OR_operator(self): result = self.cmdmgr.run_sync( 'false -a | true -a -b | false -a -b -c', on_success=self.cb_success, on_error=self.cb_error) self.confirm_broken_chain_with_OR_operator(result) async def test_async_broken_chain_with_OR_operator(self): result = await self.cmdmgr.run_async( 'false -a | true -a -b | false -a -b -c', on_success=self.cb_success, on_error=self.cb_error) self.confirm_broken_chain_with_OR_operator(result) def confirm_broken_chain_with_OR_operator(self, result): self.assertEqual(result, True) self.assertEqual(self.cb_success.calls, 1) self.assertEqual(self.cb_error.calls, 1) self.assertEqual(self.false_cb.calls, 1) self.assertEqual(self.false_cb.kwargs, [{ 'a': True, 'b': False, 'c': False }]) self.assertEqual(self.true_cb.calls, 1) self.assertEqual(self.true_cb.kwargs, [{ 'a': True, 'b': True, 'c': False }])