Example #1
0
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
Example #2
0
File: box_test.py Project: hunj/yui
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
Example #3
0
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
Example #4
0
File: conftest.py Project: hunj/yui
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()
Example #5
0
File: box_test.py Project: hunj/yui
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'
    )
Example #6
0
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")
Example #7
0
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',
    ]
Example #8
0
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"},
    )
Example #9
0
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)')
Example #10
0
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)")
Example #11
0
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
Example #12
0
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
Example #13
0
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'},
    )
Example #14
0
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)"
    )
Example #15
0
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
Example #16
0
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)')
Example #17
0
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'},
    )