async def test_multi_flag(self):
        flag1 = Flag(
            name=["flag", "f"],
            description="some flag description",
        )
        flag2 = Flag(
            name=["Flag", "F"],
            description="some flag description",
        )

        bot_username = "******"
        command_line = '/command --{}{}'.format(flag1.names[1], flag2.names[1])
        expected_args = [
            flag1,
            flag2,
        ]

        command, parsed_args = parse_telegram_command(bot_username,
                                                      command_line,
                                                      expected_args)

        self.assertEqual(command, "command")
        self.assertEqual(len(parsed_args), len(expected_args))
        self.assertTrue("flag" in parsed_args)
        self.assertTrue(parsed_args["flag"] is True)
    async def test_named_argument(self):
        arg1 = Argument(name="int_arg",
                        description="str description",
                        type=int,
                        example="5")
        arg2 = Argument(name="str_arg",
                        description="str description",
                        example="text")
        arg3 = Argument(name="float_arg",
                        description="str description",
                        type=float,
                        example="1.23",
                        optional=True,
                        default=12.5)

        bot_username = "******"
        command_line = '/command 12345 --{} "two words"'.format(arg2.name)
        expected_args = [arg1, arg2, arg3]

        command, parsed_args = parse_telegram_command(bot_username,
                                                      command_line,
                                                      expected_args)

        self.assertEqual(command, "command")
        self.assertEqual(len(parsed_args), len(expected_args))
        self.assertEqual(parsed_args[arg1.name], 12345)
        self.assertEqual(parsed_args[arg2.name], "two words")
        self.assertEqual(parsed_args[arg3.name], arg3.default)
        async def wrapped(*args, **kwargs):
            # find function arguments
            message = find_first(args, Message)

            # get bot, chat and message info
            bot = message.bot
            me = await bot.get_me()
            bot_username = me.username
            chat_id = message.chat.id

            try:
                if not await _check_permissions(message, permissions):
                    # permission denied
                    LOGGER.debug("Permission denied in chat {} for user {} for message: {}".format(
                        chat_id, message.from_user.id, message))

                    for handler in error_handlers:
                        if await handler.on_permission_error(message, permissions):
                            break

                    # don't process command
                    return

                # parse and check command target
                cmd, _ = split_command_from_args(message.text)
                _, target = split_command_from_target(bot_username, cmd)
                # check if we are allowed to process the given command target
                if not await filter_command_target(target, bot_username, command_target):
                    LOGGER.debug("Ignoring command for unspecified target {} in chat {} for user {}: {}".format(
                        target, chat_id, message.from_user.id, message))

                    # don't process command
                    return

                try:
                    # parse command and arguments
                    cmd, parsed_args = parse_telegram_command(bot_username, message.text, arguments)
                except ValueError as ex:
                    # error during argument parsing
                    logging.exception("Error parsing command arguments")

                    for handler in error_handlers:
                        if await handler.on_validation_error(message, ex, help_message):
                            break

                    return

                # convert argument names to python param naming convention (snake-case)
                kw_function_args = dict(
                    map(lambda x: (x[0].lower().replace("-", "_"), x[1]), list(parsed_args.items())))
                # execute wrapped function
                return await func(*args, **{**kw_function_args, **kwargs})
            except Exception as ex:
                # error while executing wrapped function
                logging.exception("Error in callback")
                for handler in error_handlers:
                    if await handler.on_execution_error(message, ex):
                        break
    async def test_naming_prefix_within_quote(self):
        arg1 = Argument(name="a", description="str description", example="v")
        arg_val = "--a"

        bot_username = "******"
        command_line = '/command "{}"'.format(arg_val)
        expected_args = [arg1]

        command, parsed_args = parse_telegram_command(bot_username,
                                                      command_line,
                                                      expected_args)

        self.assertEqual(parsed_args[arg1.name], arg_val)
    async def test_escape_char(self):
        arg1 = Argument(name="a", description="str description", example="v")

        arg_values = [{
            "in": 'te\\"st',
            "out": 'te"st'
        }, {
            "in": 'test\\"',
            "out": 'test"'
        }]

        bot_username = "******"
        expected_args = [arg1]

        for arg_val in arg_values:
            command_line = '/command "{}"'.format(arg_val["in"])
            command, parsed_args = parse_telegram_command(
                bot_username, command_line, expected_args)
            self.assertEqual(parsed_args[arg1.name], arg_val["out"])
    async def test_excess_floating_args(self):
        flag1 = Argument(name="flag",
                         description="some flag description",
                         flag=True,
                         example="")

        bot_username = "******"
        command_line = '/command --{} 123 haha'.format(flag1.name)
        expected_args = [
            flag1,
        ]

        command, parsed_args = parse_telegram_command(bot_username,
                                                      command_line,
                                                      expected_args)

        self.assertEqual(command, "command")
        self.assertEqual(len(parsed_args), len(expected_args))
        self.assertTrue("flag" in parsed_args)
        self.assertTrue(parsed_args["flag"] is True)
    async def test_flag_missing(self):
        flag1 = Flag(
            name="flag",
            description="some flag description",
        )

        bot_username = "******"
        command_line = '/command'.format(flag1.name)
        expected_args = [
            flag1,
        ]

        command, parsed_args = parse_telegram_command(bot_username,
                                                      command_line,
                                                      expected_args)

        self.assertEqual(command, "command")
        self.assertEqual(len(parsed_args), len(expected_args))
        self.assertTrue("flag" in parsed_args)
        self.assertTrue(parsed_args["flag"] is False)