def test_box_class(): box = Box() assert not box.apps assert not box.tasks @box.command('test1') async def test1(bot, event): """ TEST SHORT HELP LONG CAT IS LONG """ h1 = box.apps.pop() assert isinstance(h1, App) assert h1.is_command assert h1.use_shlex assert h1.handler == test1 assert h1.short_help == 'TEST SHORT HELP' assert h1.help == 'LONG CAT IS LONG' assert not box.tasks @box.command('test2', ['t2'], use_shlex=False) async def test2(): """Short only""" h2 = box.apps.pop() assert isinstance(h2, App) assert h2.is_command assert not h2.use_shlex assert h2.handler == test2 assert h2.short_help == 'Short only' assert h2.help is None assert not box.tasks @box.on(Hello) async def test3(): pass h3 = box.apps.pop() assert isinstance(h3, App) assert not h3.is_command assert not h3.use_shlex assert h3.handler == test3 assert not box.tasks @box.cron('*/3 * * * *') async def test4(): pass assert box.tasks[0].spec == '*/3 * * * *' assert box.tasks[0].handler == test4
def test_box_class(): box = Box() assert not box.handlers assert not box.crontabs @box.command(0) async def test1(bot, event): """ TEST SHORT HELP LONG CAT IS LONG """ h1 = box.handlers.pop() assert isinstance(h1, Handler) assert h1.is_command assert h1.use_shlex assert h1.callback == test1 assert h1.short_help == 'TEST SHORT HELP' assert h1.help == 'LONG CAT IS LONG' assert not box.crontabs @box.command(1, ['t2'], use_shlex=False) async def test2(): """Short only""" h2 = box.handlers.pop() assert isinstance(h2, Handler) assert h2.is_command assert not h2.use_shlex assert h2.callback == test2 assert h2.short_help == 'Short only' assert h2.help is None assert not box.crontabs @box.on(Hello) async def test3(): pass h3 = box.handlers.pop() assert isinstance(h3, Handler) assert not h3.is_command assert not h3.use_shlex assert h3.callback == test3 assert not box.crontabs @box.crontab('*/3 * * * *') async def test4(): pass assert box.crontabs[0].spec == '*/3 * * * *' assert box.crontabs[0].func == test4
def test_handler_class(): box = Box() @box.command('test') @option('--foo', '-f') @option('--bar') @argument('baz') @argument('kw', nargs=-1, concat=True) async def test(bot, event: Message, foo: int, bar: str, baz: str, kw: str): """ TEST TITLE LONG CAT IS LONG """ handler: Handler = box.handlers['message'][None]['test'] assert handler.callback == test assert handler.channel_validator is None assert handler.is_command assert handler.use_shlex assert handler.short_help == 'TEST TITLE' assert handler.help == """LONG CAT IS LONG""" assert handler.signature.parameters['bot'] assert handler.signature.parameters['event'] assert handler.signature.parameters['event'].annotation == Message assert handler.signature.parameters['foo'] assert handler.signature.parameters['foo'].annotation == int assert handler.signature.parameters['bar'] assert handler.signature.parameters['bar'].annotation == str assert handler.signature.parameters['baz'] assert handler.signature.parameters['baz'].annotation == str assert handler.signature.parameters['kw'] assert handler.signature.parameters['kw'].annotation == str option_chunks = shlex.split('-f 111 --bar aaaa first_arg second is long') options, argument_chunks = handler.parse_options(option_chunks) assert options['foo'] == 111 assert options['bar'] == 'aaaa' arguments, remain_chunks = handler.parse_arguments(argument_chunks) assert arguments['baz'] == 'first_arg' assert arguments['kw'] == 'second is long' assert not remain_chunks
def fx_engine(request): try: database_url = request.config.getoption('--database-url') except ValueError: database_url = None config = gen_config() if database_url: config.DATABASE_URL = database_url bot = Bot(config, using_box=Box()) engine = bot.config.DATABASE_ENGINE try: metadata = Base.metadata metadata.drop_all(bind=engine) metadata.create_all(bind=engine) yield engine metadata.drop_all(bind=engine) finally: engine.dispose()
def test_handler_class(): box = Box() @box.command('test', aliases=['tttt']) @option('--foo', '-f') @option('--bar') @argument('baz') @argument('kw', nargs=-1, concat=True) async def test(bot, event: Message, foo: int, bar: str, baz: str, kw: str): """ TEST TITLE LONG CAT IS LONG """ handler: Handler = box.handlers.pop() assert handler.name == 'test' assert handler.aliases == ['tttt'] assert handler.names == ['tttt', 'test'] assert handler.callback == test assert handler.channel_validator is None assert handler.is_command assert handler.use_shlex assert handler.has_short_help assert handler.has_full_help assert handler.short_help == 'TEST TITLE' assert handler.help == """LONG CAT IS LONG""" assert handler.get_short_help('=') == '`=test`: TEST TITLE' assert handler.get_full_help('=') == ( '*=test*\n' '(Aliases: `=tttt`)\n' 'TEST TITLE\n\n' 'LONG\n' 'CAT\n' 'IS\n' 'LONG' )
def test_basic_app(): box = Box() @box.command("test", aliases=["tttt"]) @option("--foo", "-f") @option("--bar") @argument("baz") @argument("kw", nargs=-1, concat=True) async def test(bot, event: Message, foo: int, bar: str, baz: str, kw: str): """ TEST TITLE LONG CAT IS LONG """ app: App = box.apps.pop() assert app.name == "test" assert app.aliases == ["tttt"] assert app.names == ["tttt", "test"] assert app.handler == test assert app.is_command assert app.use_shlex assert app.has_short_help assert app.has_full_help assert app.short_help == "TEST TITLE" assert (app.help == """LONG CAT IS LONG""") assert app.get_short_help("=") == "`=test`: TEST TITLE" assert app.get_full_help("=") == ("*=test*\n" "(Aliases: `=tttt`)\n" "TEST TITLE\n\n" "LONG\n" "CAT\n" "IS\n" "LONG")
def test_bot_init(monkeypatch, fx_config): importlib = FakeImportLib() monkeypatch.setattr("importlib.import_module", importlib.import_module) fx_config.APPS = ['yui.app1', 'yui.app2'] box = Box() bot = Bot(fx_config, using_box=box) assert bot.config == fx_config assert bot.channels == [] assert bot.ims == [] assert bot.groups == [] assert bot.restart is False assert isinstance(bot.api, SlackAPI) assert bot.box is box assert isinstance(bot.queue, asyncio.Queue) assert importlib.import_queue == [ 'yui.app1', 'yui.app2', ]
async def test_call(bot_config, response_mock): token = "asdf1234" response_mock.post( "https://slack.com/api/test11", body=json.dumps({"res": "hello world!"}), headers={"content-type": "application/json"}, status=200, ) response_mock.post( "https://slack.com/api/test12", body=json.dumps({ "res": "hello world!", "data": { "extra": "wow" } }), headers={"content-type": "application/json"}, status=200, ) response_mock.post( "https://slack.com/api/test21", body=json.dumps({"error": "aaa"}), headers={"content-type": "application/json"}, status=404, ) response_mock.post( "https://slack.com/api/test22", body=json.dumps({"error": "aaa"}), headers={"content-type": "application/json"}, status=404, ) response_mock.post( "https://slack.com/api/test3", body=json.dumps({"res": "hello world!"}), headers={"content-type": "application/json"}, status=200, ) box = Box() bot = Bot(bot_config, using_box=box) bot.api.throttle_interval = defaultdict(lambda: timedelta(0)) res = await bot.call("test11") assert res == APIResponse( body={"res": "hello world!"}, status=200, headers={"content-type": "application/json"}, ) res = await bot.call("test12", data={"extra": "wow"}) assert res == APIResponse( body={ "res": "hello world!", "data": { "extra": "wow" } }, status=200, headers={"content-type": "application/json"}, ) res = await bot.call("test21") assert res == APIResponse( body={"error": "aaa"}, status=404, headers={"content-type": "application/json"}, ) res = await bot.call("test22", data={"extra": "wow"}) assert res == APIResponse( body={"error": "aaa"}, status=404, headers={"content-type": "application/json"}, ) res = await bot.call("test3", token=token) assert res == APIResponse( body={"res": "hello world!"}, status=200, headers={"content-type": "application/json"}, )
def test_handler_parse_argument(): box = Box() @box.command('test') @argument('non_type') @argument('transform_non_type', transform_func=str_to_date()) @argument('container', nargs=3, container_cls=set, type_=float) @argument('container_with_typing', nargs=3) @argument('container_with_transform', nargs=2, container_cls=list, transform_func=str_to_date()) async def test( non_type, transform_non_type: datetime.date, container_with_typing: List[int], container_with_transform: List[datetime.date], ): pass handler: Handler = box.handlers['message'][None]['test'] argument_chunks = shlex.split('hello ' '2017-10-07 ' '3.3 1.1 2.2 ' '1 2 3 ' '2017-10-07 2017-10-24 ') arguments, remain_chunks = handler.parse_arguments(argument_chunks) assert arguments['non_type'] == 'hello' assert arguments['transform_non_type'] == datetime.date(2017, 10, 7) assert arguments['container'] == {1.1, 2.2, 3.3} assert arguments['container_with_typing'] == [1, 2, 3] assert arguments['container_with_transform'] == [ datetime.date(2017, 10, 7), datetime.date(2017, 10, 24), ] @box.command('test2') @argument('args', nargs=-1) async def test2(args): pass handler: Handler = box.handlers['message'][None]['test2'] argument_chunks = shlex.split('') with pytest.raises(SyntaxError) as e: handler.parse_arguments(argument_chunks) assert e.value.msg == ('args: incorrect argument value count.' ' expected >0, 0 given.') @box.command('test3') @argument('args', nargs=2) @argument('concat', nargs=3, concat=True) async def test3(args): pass handler: Handler = box.handlers['message'][None]['test3'] argument_chunks = shlex.split('1') with pytest.raises(SyntaxError) as e: handler.parse_arguments(argument_chunks) assert e.value.msg == ('args: incorrect argument value count.' ' expected 2, 1 given.') argument_chunks = shlex.split('1 2 hell o world') arguments, remain_chunks = handler.parse_arguments(argument_chunks) assert arguments['args'] == ('1', '2') assert arguments['concat'] == 'hell o world' assert not remain_chunks @box.command('test4') @argument('args') async def test4(args: int): pass handler: Handler = box.handlers['message'][None]['test4'] argument_chunks = shlex.split('asdf') with pytest.raises(SyntaxError) as e: handler.parse_arguments(argument_chunks) assert e.value.msg == ("args: invalid type of argument value" "(invalid literal for int() with " "base 10: 'asdf')") @box.command('test5') @argument('args', transform_func=str_to_date()) async def test5(args): pass handler: Handler = box.handlers['message'][None]['test5'] argument_chunks = shlex.split('2017-10-99') with pytest.raises(SyntaxError) as e: handler.parse_arguments(argument_chunks) assert e.value.msg == ('args: fail to transform argument value ' '(day is out of range for month)') @box.command('test6') @argument('args', nargs=2, transform_func=str_to_date()) async def test6(args): pass handler: Handler = box.handlers['message'][None]['test6'] argument_chunks = shlex.split('2017-10-99 2017-10-00') with pytest.raises(SyntaxError) as e: handler.parse_arguments(argument_chunks) assert e.value.msg == ('args: fail to transform argument value ' '(day is out of range for month)')
def test_handler_parse_option(): box = Box() def callable_default(): return 'hello' @box.command('test') @option('--required-option', required=True) @option('--dest-change-option', dest='dest_changed_option') @option('--is-flag', is_flag=True) @option('--multiple', multiple=True) @option('--container', container_cls=set, type_=float, nargs=2) @option('--callable-default', default=callable_default) @option('--non-type') @option('--default-option', default='!!!') @option('--transform', type_=int, transform_func=value_range(1, 10)) @option('--transform-non-type', transform_func=str_to_date()) @option('--transform-container', type_=int, transform_func=value_range(1, 10), container_cls=set, nargs=3) @option('--transform-two', transform_func=str_to_date(), container_cls=list, nargs=2) async def test( required_option: int, dest_changed_option: int, is_flag: bool, multiple: List[int], container, callable_default: str, non_type, default_option, transform: int, transform_non_type: datetime.date, transform_container: Set[int], transform_two: List[datetime.date], ): pass handler: Handler = box.handlers['message'][None]['test'] option_chunks = shlex.split('--required-option 1111 ' '--dest-change-option 2222 ' '--is-flag ' '--multiple 3333 --multiple=4444 ' '--container 55.55 66.66 ' '--non-type world ' '--transform 4 ' '--transform-non-type 2017-10-07 ' '--transform-container 4 6 2 ' '--transform-two 2017-10-07 2017-10-24 ') options, argument_chunks = handler.parse_options(option_chunks) assert options['required_option'] == 1111 assert options['dest_changed_option'] == 2222 assert options['is_flag'] assert options['multiple'] == [3333, 4444] assert options['container'] == {55.55, 66.66} assert options['callable_default'] == 'hello' assert options['non_type'] == 'world' assert options['default_option'] == '!!!' assert options['transform'] == 4 assert options['transform_non_type'] == datetime.date(2017, 10, 7) assert options['transform_container'] == {2, 4, 6} assert options['transform_two'] == [ datetime.date(2017, 10, 7), datetime.date(2017, 10, 24), ] assert not argument_chunks option_chunks = shlex.split('') with pytest.raises(SyntaxError) as e: handler.parse_options(option_chunks) assert e.value.msg == ('--required-option: incorrect option value count.' ' expected 1, 0 given.') option_chunks = shlex.split('--required-option 1111 ' '--container 55.55 ') with pytest.raises(SyntaxError) as e: handler.parse_options(option_chunks) assert e.value.msg == ("--container: incorrect option value count." " expected 2, 1 given.") option_chunks = shlex.split('--required-option 1111 ' '--container a b ') with pytest.raises(SyntaxError) as e: handler.parse_options(option_chunks) assert e.value.msg == ("--container: invalid type of option value" "(could not convert string to float: 'a')") option_chunks = shlex.split('--required-option 1111 ' '--transform-non-type 2017-10-99') with pytest.raises(SyntaxError) as e: handler.parse_options(option_chunks) assert e.value.msg == ("--transform-non-type: fail to transform option " "value (day is out of range for month)") option_chunks = shlex.split('--required-option 1111 ' '--transform-two 2017-10-99 2017-10-00') with pytest.raises(SyntaxError) as e: handler.parse_options(option_chunks) assert e.value.msg == ("--transform-two: fail to transform option " "value (day is out of range for month)")
def test_box_class(): box = Box() assert not box.aliases assert not box.handlers assert not box.crontabs @box.command('test1') async def test1(bot, event): """ TEST SHORT HELP LONG CAT IS LONG """ assert not box.aliases assert type(box.handlers['message'][None]['test1']) == Handler assert box.handlers['message'][None]['test1'].is_command assert box.handlers['message'][None]['test1'].use_shlex assert box.handlers['message'][None]['test1'].callback == test1 params = set( box.handlers['message'][None]['test1'].signature.parameters.keys()) assert params == {'bot', 'event'} assert box.handlers['message'][None]['test1'].short_help == ( 'TEST SHORT HELP') assert box.handlers['message'][None]['test1'].help == ('LONG CAT IS LONG') assert not box.crontabs @box.command('test2', ['t2'], use_shlex=False) async def test2(): """Short only""" assert box.aliases[None]['t2'] == 'test2' assert type(box.handlers['message'][None]['test1']) == Handler assert type(box.handlers['message'][None]['test2']) == Handler assert box.handlers['message'][None]['test1'].is_command assert box.handlers['message'][None]['test2'].is_command assert box.handlers['message'][None]['test1'].use_shlex assert not box.handlers['message'][None]['test2'].use_shlex assert box.handlers['message'][None]['test1'].callback == test1 assert box.handlers['message'][None]['test2'].callback == test2 assert box.handlers['message'][None]['test2'].short_help == ('Short only') assert box.handlers['message'][None]['test2'].help is None assert not box.crontabs @box.on(Hello) async def test3(): pass assert box.aliases[None]['t2'] == 'test2' assert type(box.handlers['message'][None]['test1']) == Handler assert type(box.handlers['message'][None]['test2']) == Handler assert type(box.handlers['hello'][None]['tests.box_test.test3']) == Handler assert box.handlers['message'][None]['test1'].is_command assert box.handlers['message'][None]['test2'].is_command assert not box.handlers['hello'][None]['tests.box_test.test3'].is_command assert box.handlers['message'][None]['test1'].is_command assert not box.handlers['message'][None]['test2'].use_shlex assert not box.handlers['hello'][None]['tests.box_test.test3'].use_shlex assert box.handlers['message'][None]['test1'].callback == test1 assert box.handlers['message'][None]['test2'].callback == test2 assert box.handlers['hello'][None]['tests.box_test.test3'].callback == \ test3 assert not box.crontabs @box.crontab('*/3 * * * *') async def test4(): pass assert box.aliases[None]['t2'] == 'test2' assert type(box.handlers['message'][None]['test1']) == Handler assert type(box.handlers['message'][None]['test2']) == Handler assert type(box.handlers['hello'][None]['tests.box_test.test3']) == Handler assert box.handlers['message'][None]['test1'].is_command assert box.handlers['message'][None]['test2'].is_command assert not box.handlers['hello'][None]['tests.box_test.test3'].is_command assert box.handlers['message'][None]['test1'].is_command assert not box.handlers['message'][None]['test2'].use_shlex assert not box.handlers['hello'][None]['tests.box_test.test3'].use_shlex assert box.handlers['message'][None]['test1'].callback == test1 assert box.handlers['message'][None]['test2'].callback == test2 assert box.handlers['hello'][None]['tests.box_test.test3'].callback == \ test3 assert box.crontabs[0].spec == '*/3 * * * *' assert box.crontabs[0].func == test4
def test_box_class(): box = Box() assert not box.apps assert not box.tasks @box.command('test1') async def test1(bot, event): """ TEST SHORT HELP LONG CAT IS LONG """ h1 = box.apps.pop() assert isinstance(h1, App) assert h1.is_command assert h1.use_shlex assert h1.handler == test1 assert h1.short_help == 'TEST SHORT HELP' assert h1.help == 'LONG CAT IS LONG' assert not box.tasks @box.command('test2', ['t2'], use_shlex=False) async def test2(): """Short only""" h2 = box.apps.pop() assert isinstance(h2, App) assert h2.is_command assert not h2.use_shlex assert h2.handler == test2 assert h2.short_help == 'Short only' assert h2.help is None assert not box.tasks @box.on(Hello) async def test3(): pass h3 = box.apps.pop() assert isinstance(h3, App) assert not h3.is_command assert not h3.use_shlex assert h3.handler == test3 assert not box.tasks @box.cron('*/3 * * * *') async def test4(): pass assert box.tasks[0].spec == '*/3 * * * *' assert box.tasks[0].handler == test4 @box.on('message') async def test4(): pass h4 = box.apps.pop() assert isinstance(h4, App) assert not h4.is_command assert not h4.use_shlex assert h4.handler == test4 box.assert_config_required('OWNER_TOKEN', str) assert box.config_required['OWNER_TOKEN'] == str box.assert_channel_required('game') assert box.channel_required == {'game'} box.assert_channels_required('test') assert box.channels_required == {'test'} box.assert_user_required('admin') assert box.user_required == {'admin'} box.assert_users_required('player') assert box.users_required == {'player'} class Test(App): pass testapp = Test(handler=test4, type='message', subtype=None) box.register(testapp) assert box.apps.pop() == testapp
async def test_call(fx_config, response_mock): token = 'asdf1234' response_mock.post( 'https://slack.com/api/test11', body=ujson.dumps({ 'res': 'hello world!', }), headers={'content-type': 'application/json'}, status=200, ) response_mock.post( 'https://slack.com/api/test12', body=ujson.dumps({ 'res': 'hello world!', 'data': { 'extra': 'wow', }, }), headers={'content-type': 'application/json'}, status=200, ) response_mock.post( 'https://slack.com/api/test21', body=ujson.dumps({ 'error': 'aaa', }), headers={'content-type': 'application/json'}, status=404, ) response_mock.post( 'https://slack.com/api/test22', body=ujson.dumps({ 'error': 'aaa', }), headers={'content-type': 'application/json'}, status=404, ) response_mock.post( 'https://slack.com/api/test3', body=ujson.dumps({ 'res': 'hello world!', }), headers={'content-type': 'application/json'}, status=200, ) box = Box() bot = Bot(fx_config, using_box=box) res = await bot.call('test11') assert res == APIResponse( body={'res': 'hello world!'}, status=200, headers={'content-type': 'application/json'}, ) res = await bot.call('test12', data={'extra': 'wow'}) assert res == APIResponse( body={ 'res': 'hello world!', 'data': { 'extra': 'wow' } }, status=200, headers={'content-type': 'application/json'}, ) res = await bot.call('test21') assert res == APIResponse( body={'error': 'aaa'}, status=404, headers={'content-type': 'application/json'}, ) res = await bot.call('test22', data={'extra': 'wow'}) assert res == APIResponse( body={'error': 'aaa'}, status=404, headers={'content-type': 'application/json'}, ) res = await bot.call('test3', token=token) assert res == APIResponse( body={'res': 'hello world!'}, status=200, headers={'content-type': 'application/json'}, )
def test_parse_option_and_arguments(): box = Box() def callable_default(): return "hello" @box.command("test-option") @option("--required-option", required=True) @option("--dest-change-option", dest="dest_changed_option") @option("--is-flag", is_flag=True) @option("--multiple", multiple=True) @option("--container", container_cls=set, type_=float, nargs=2) @option("--callable-default", default=callable_default) @option("--non-type") @option("--default-option", default="!!!") @option("--transform", type_=int, transform_func=value_range(1, 10)) @option("--transform-non-type", transform_func=str_to_date()) @option( "--transform-container", type_=int, transform_func=value_range(1, 10), container_cls=set, nargs=3, ) @option( "--transform-two", transform_func=str_to_date(), container_cls=list, nargs=2, ) async def test_option( required_option: int, dest_changed_option: int, is_flag: bool, multiple: list[int], container, callable_default: str, non_type, default_option, transform: int, transform_non_type: datetime.date, transform_container: set[int], transform_two: list[datetime.date], ): pass app: App = box.apps.pop() chunks = shlex.split( "--dest-change-option=2222 " "--is-flag " "--multiple 3333 --multiple=4444 " "--container 55.55 66.66 " "--non-type world " "--transform 4 " "--transform-non-type 2017-10-07 " "--transform-container 4 6 2 " "--transform-two 2017-10-07 2017-10-24 " "--required-option 1111 " ) kw, remain_chunks = parse_option_and_arguments(app.handler, chunks) assert kw["required_option"] == 1111 assert kw["dest_changed_option"] == 2222 assert kw["is_flag"] assert kw["multiple"] == [3333, 4444] assert kw["container"] == {55.55, 66.66} assert kw["callable_default"] == "hello" assert kw["non_type"] == "world" assert kw["default_option"] == "!!!" assert kw["transform"] == 4 assert kw["transform_non_type"] == datetime.date(2017, 10, 7) assert kw["transform_container"] == {2, 4, 6} assert kw["transform_two"] == [ datetime.date(2017, 10, 7), datetime.date(2017, 10, 24), ] assert not remain_chunks chunks = shlex.split("") with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ( "--required-option: incorrect option value count." " expected 1, 0 given." ) chunks = shlex.split("--required-option 1111 " "--container 55.55 ") with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ( "--container: incorrect option value count." " expected 2, 1 given." ) chunks = shlex.split("--required-option 1111 " "--container a b ") with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ( "--container: invalid type of option value" "(Can not find matching caster)" ) chunks = shlex.split( "--required-option 1111 " "--transform-non-type 2017-10-99" ) with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ( "--transform-non-type: fail to transform option " "value (day is out of range for month)" ) chunks = shlex.split( "--required-option 1111 " "--transform-two 2017-10-99 2017-10-00" ) with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ( "--transform-two: fail to transform option " "value (day is out of range for month)" ) @box.command("test-argument1") @argument("non_type") @argument("transform_non_type", transform_func=str_to_date()) @argument("container", nargs=3, container_cls=set, type_=float) @argument("container_with_typing", nargs=3) @argument( "container_with_transform", nargs=2, container_cls=list, transform_func=str_to_date(), ) async def test_argument1( non_type, transform_non_type: datetime.date, container_with_typing: list[int], container_with_transform: list[datetime.date], ): pass app: App = box.apps.pop() chunks = shlex.split( "hello " "2017-10-07 " "3.3 1.1 2.2 " "1 2 3 " "2017-10-07 2017-10-24 " ) kw, remain_chunks = parse_option_and_arguments(app.handler, chunks) assert kw["non_type"] == "hello" assert kw["transform_non_type"] == datetime.date(2017, 10, 7) assert kw["container"] == {1.1, 2.2, 3.3} assert kw["container_with_typing"] == [1, 2, 3] assert kw["container_with_transform"] == [ datetime.date(2017, 10, 7), datetime.date(2017, 10, 24), ] @box.command("test-argument2") @argument("args", nargs=-1) async def test_argument2(args): pass app: App = box.apps.pop() chunks = shlex.split("") with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ( "args: incorrect argument value count." " expected >0, 0 given." ) @box.command("test-argument3") @argument("args", nargs=2) @argument("concat", nargs=3, concat=True) async def test_argument3(args): pass app: App = box.apps.pop() chunks = shlex.split("1") with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ( "args: incorrect argument value count." " expected 2, 1 given." ) chunks = shlex.split("1 2 hell o world") kw, remain_chunks = parse_option_and_arguments(app.handler, chunks) assert kw["args"] == ("1", "2") assert kw["concat"] == "hell o world" assert not remain_chunks @box.command("test-argument4") @argument("args") async def test_argument4(args: int): pass app: App = box.apps.pop() chunks = shlex.split("asdf") with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ( "args: invalid type of argument value(Can not find matching caster)" ) @box.command("test-argument5") @argument("args", transform_func=str_to_date()) async def test_argument5(args): pass app: App = box.apps.pop() chunks = shlex.split("2017-10-99") with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ( "args: fail to transform argument value " "(day is out of range for month)" ) @box.command("test-argument6") @argument("args", nargs=2, transform_func=str_to_date()) async def test_argument6(args): pass app: App = box.apps.pop() chunks = shlex.split("2017-10-99 2017-10-00") with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ( "args: fail to transform argument value " "(day is out of range for month)" )
def test_box_class(): box = Box() assert not box.apps assert not box.tasks @box.command("test1") async def test1(bot, event): """ TEST SHORT HELP LONG CAT IS LONG """ h1 = box.apps.pop() assert isinstance(h1, App) assert h1.is_command assert h1.use_shlex assert h1.handler == test1 assert h1.short_help == "TEST SHORT HELP" assert h1.help == "LONG CAT IS LONG" assert not box.tasks @box.command("test2", ["t2"], use_shlex=False) async def test2(): """Short only""" h2 = box.apps.pop() assert isinstance(h2, App) assert h2.is_command assert not h2.use_shlex assert h2.handler == test2 assert h2.short_help == "Short only" assert h2.help is None assert not box.tasks @box.on(Hello) async def test3(): pass h3 = box.apps.pop() assert isinstance(h3, App) assert not h3.is_command assert not h3.use_shlex assert h3.handler == test3 assert not box.tasks @box.cron("*/3 * * * *") async def test4(): pass assert box.tasks[0].spec == "*/3 * * * *" assert box.tasks[0].handler == test4 @box.on("message") async def test4(): pass h4 = box.apps.pop() assert isinstance(h4, App) assert not h4.is_command assert not h4.use_shlex assert h4.handler == test4 box.assert_config_required("OWNER_TOKEN", str) assert box.config_required["OWNER_TOKEN"] == str box.assert_channel_required("game") assert box.channel_required == {"game"} box.assert_channels_required("test") assert box.channels_required == {"test"} box.assert_user_required("admin") assert box.user_required == {"admin"} box.assert_users_required("player") assert box.users_required == {"player"} class Test(App): pass testapp = Test(handler=test4, type="message", subtype=None) box.register(testapp) assert box.apps.pop() == testapp
def test_parse_option_and_arguments(): box = Box() def callable_default(): return 'hello' @box.command('test-option') @option('--required-option', required=True) @option('--dest-change-option', dest='dest_changed_option') @option('--is-flag', is_flag=True) @option('--multiple', multiple=True) @option('--container', container_cls=set, type_=float, nargs=2) @option('--callable-default', default=callable_default) @option('--non-type') @option('--default-option', default='!!!') @option('--transform', type_=int, transform_func=value_range(1, 10)) @option('--transform-non-type', transform_func=str_to_date()) @option('--transform-container', type_=int, transform_func=value_range(1, 10), container_cls=set, nargs=3) @option('--transform-two', transform_func=str_to_date(), container_cls=list, nargs=2) async def test_option( required_option: int, dest_changed_option: int, is_flag: bool, multiple: List[int], container, callable_default: str, non_type, default_option, transform: int, transform_non_type: datetime.date, transform_container: Set[int], transform_two: List[datetime.date], ): pass app: App = box.apps.pop() chunks = shlex.split( '--dest-change-option=2222 ' '--is-flag ' '--multiple 3333 --multiple=4444 ' '--container 55.55 66.66 ' '--non-type world ' '--transform 4 ' '--transform-non-type 2017-10-07 ' '--transform-container 4 6 2 ' '--transform-two 2017-10-07 2017-10-24 ' '--required-option 1111 ' ) kw, remain_chunks = parse_option_and_arguments(app.handler, chunks) assert kw['required_option'] == 1111 assert kw['dest_changed_option'] == 2222 assert kw['is_flag'] assert kw['multiple'] == [3333, 4444] assert kw['container'] == {55.55, 66.66} assert kw['callable_default'] == 'hello' assert kw['non_type'] == 'world' assert kw['default_option'] == '!!!' assert kw['transform'] == 4 assert kw['transform_non_type'] == datetime.date(2017, 10, 7) assert kw['transform_container'] == {2, 4, 6} assert kw['transform_two'] == [ datetime.date(2017, 10, 7), datetime.date(2017, 10, 24), ] assert not remain_chunks chunks = shlex.split('') with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ('--required-option: incorrect option value count.' ' expected 1, 0 given.') chunks = shlex.split( '--required-option 1111 ' '--container 55.55 ' ) with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ("--container: incorrect option value count." " expected 2, 1 given.") chunks = shlex.split( '--required-option 1111 ' '--container a b ' ) with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ("--container: invalid type of option value" "(could not convert string to float: 'a')") chunks = shlex.split( '--required-option 1111 ' '--transform-non-type 2017-10-99' ) with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ("--transform-non-type: fail to transform option " "value (day is out of range for month)") chunks = shlex.split( '--required-option 1111 ' '--transform-two 2017-10-99 2017-10-00' ) with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ("--transform-two: fail to transform option " "value (day is out of range for month)") @box.command('test-argument1') @argument('non_type') @argument('transform_non_type', transform_func=str_to_date()) @argument('container', nargs=3, container_cls=set, type_=float) @argument('container_with_typing', nargs=3) @argument('container_with_transform', nargs=2, container_cls=list, transform_func=str_to_date()) async def test_argument1( non_type, transform_non_type: datetime.date, container_with_typing: List[int], container_with_transform: List[datetime.date], ): pass app: App = box.apps.pop() chunks = shlex.split( 'hello ' '2017-10-07 ' '3.3 1.1 2.2 ' '1 2 3 ' '2017-10-07 2017-10-24 ' ) kw, remain_chunks = parse_option_and_arguments(app.handler, chunks) assert kw['non_type'] == 'hello' assert kw['transform_non_type'] == datetime.date(2017, 10, 7) assert kw['container'] == {1.1, 2.2, 3.3} assert kw['container_with_typing'] == [1, 2, 3] assert kw['container_with_transform'] == [ datetime.date(2017, 10, 7), datetime.date(2017, 10, 24), ] @box.command('test-argument2') @argument('args', nargs=-1) async def test_argument2(args): pass app: App = box.apps.pop() chunks = shlex.split('') with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ('args: incorrect argument value count.' ' expected >0, 0 given.') @box.command('test-argument3') @argument('args', nargs=2) @argument('concat', nargs=3, concat=True) async def test_argument3(args): pass app: App = box.apps.pop() chunks = shlex.split('1') with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ('args: incorrect argument value count.' ' expected 2, 1 given.') chunks = shlex.split('1 2 hell o world') kw, remain_chunks = parse_option_and_arguments(app.handler, chunks) assert kw['args'] == ('1', '2') assert kw['concat'] == 'hell o world' assert not remain_chunks @box.command('test-argument4') @argument('args') async def test_argument4(args: int): pass app: App = box.apps.pop() chunks = shlex.split('asdf') with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ("args: invalid type of argument value" "(invalid literal for int() with " "base 10: 'asdf')") @box.command('test-argument5') @argument('args', transform_func=str_to_date()) async def test_argument5(args): pass app: App = box.apps.pop() chunks = shlex.split('2017-10-99') with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ('args: fail to transform argument value ' '(day is out of range for month)') @box.command('test-argument6') @argument('args', nargs=2, transform_func=str_to_date()) async def test_argument6(args): pass app: App = box.apps.pop() chunks = shlex.split('2017-10-99 2017-10-00') with pytest.raises(SyntaxError) as e: parse_option_and_arguments(app.handler, chunks) assert e.value.msg == ('args: fail to transform argument value ' '(day is out of range for month)')
async def test_call(event_loop, bot_config, response_mock): token = 'asdf1234' response_mock.post( 'https://slack.com/api/test11', body=json.dumps({'res': 'hello world!'}), headers={'content-type': 'application/json'}, status=200, ) response_mock.post( 'https://slack.com/api/test12', body=json.dumps({ 'res': 'hello world!', 'data': { 'extra': 'wow' } }), headers={'content-type': 'application/json'}, status=200, ) response_mock.post( 'https://slack.com/api/test21', body=json.dumps({'error': 'aaa'}), headers={'content-type': 'application/json'}, status=404, ) response_mock.post( 'https://slack.com/api/test22', body=json.dumps({'error': 'aaa'}), headers={'content-type': 'application/json'}, status=404, ) response_mock.post( 'https://slack.com/api/test3', body=json.dumps({'res': 'hello world!'}), headers={'content-type': 'application/json'}, status=200, ) box = Box() bot = Bot(bot_config, event_loop, using_box=box) bot.api.throttle_interval = defaultdict(lambda: timedelta(0)) res = await bot.call('test11') assert res == APIResponse( body={'res': 'hello world!'}, status=200, headers={'content-type': 'application/json'}, ) res = await bot.call('test12', data={'extra': 'wow'}) assert res == APIResponse( body={ 'res': 'hello world!', 'data': { 'extra': 'wow' } }, status=200, headers={'content-type': 'application/json'}, ) res = await bot.call('test21') assert res == APIResponse( body={'error': 'aaa'}, status=404, headers={'content-type': 'application/json'}, ) res = await bot.call('test22', data={'extra': 'wow'}) assert res == APIResponse( body={'error': 'aaa'}, status=404, headers={'content-type': 'application/json'}, ) res = await bot.call('test3', token=token) assert res == APIResponse( body={'res': 'hello world!'}, status=200, headers={'content-type': 'application/json'}, )