mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 14:35:36 +01:00
moved teloxide::utils::command::tests to tests/command.rs
This commit is contained in:
parent
54276aa8ba
commit
1475b62e57
2 changed files with 195 additions and 188 deletions
|
@ -86,9 +86,10 @@ pub use teloxide_macros::BotCommand;
|
|||
///
|
||||
/// 4. `#[command(parser = "parser")]`
|
||||
/// Change the parser of arguments. Possible values:
|
||||
/// - `default` - it also will be used if `parser` attribute will not be specified.
|
||||
/// It can only put all text after first space into first argument, which implement
|
||||
/// FromStr trait.
|
||||
/// - `default` - it also will be used if `parser` attribute will not be
|
||||
/// specified.
|
||||
/// It can only put all text after first space into first argument, which
|
||||
/// implement FromStr trait.
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use teloxide::utils::command::BotCommand;
|
||||
|
@ -99,12 +100,14 @@ pub use teloxide_macros::BotCommand;
|
|||
/// Text(String),
|
||||
/// }
|
||||
///
|
||||
/// let command = AdminCommand::parse("/text hello my dear friend!", "").unwrap();
|
||||
/// let command =
|
||||
/// AdminCommand::parse("/text hello my dear friend!", "").unwrap();
|
||||
/// assert_eq!(command, Command::Text("hello my dear friend!".to_string()));
|
||||
/// ```
|
||||
/// - `split` - parse args by split incoming text by value specified in `separator`
|
||||
/// attribute. By default use space seperator. All args must implement FromStr trait.
|
||||
/// Example:
|
||||
/// - `split` - parse args by split incoming text by value specified in
|
||||
/// `separator`
|
||||
/// attribute. By default use space seperator. All args must implement FromStr
|
||||
/// trait. Example:
|
||||
/// ```
|
||||
/// use teloxide::utils::command::BotCommand;
|
||||
///
|
||||
|
@ -117,7 +120,8 @@ pub use teloxide_macros::BotCommand;
|
|||
/// let command = AdminCommand::parse("/nums 1 32 -5", "").unwrap();
|
||||
/// assert_eq!(command, Command::Nums(1, 32, -5));
|
||||
/// ```
|
||||
/// - `custom_parser` - you can use your own parser, which must used signature `Fn(String) -> Result<Tuple, ParseError>`
|
||||
/// - `custom_parser` - you can use your own parser, which must used signature
|
||||
/// `Fn(String) -> Result<Tuple, ParseError>`
|
||||
/// where `Tuple` - tuple with all fields in type. Allowed only on variant.
|
||||
/// Example:
|
||||
/// ```
|
||||
|
@ -126,10 +130,14 @@ pub use teloxide_macros::BotCommand;
|
|||
/// fn accept_two_digits(input: String) -> Result<(u8), ParseError> {
|
||||
/// match input.len() {
|
||||
/// 2 => {
|
||||
/// let num = input.parse().map_err(|_|ParseError::IncorrectFormat)?;
|
||||
/// let num =
|
||||
/// input.parse().map_err(|_| ParseError::IncorrectFormat)?;
|
||||
/// Ok((num))
|
||||
/// }
|
||||
/// len => Err(ParseError::Custom(format!("Only 2 digits allowed, not {}", len)))
|
||||
/// len => Err(ParseError::Custom(format!(
|
||||
/// "Only 2 digits allowed, not {}",
|
||||
/// len
|
||||
/// ))),
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
|
@ -190,15 +198,20 @@ pub trait BotCommand: Sized {
|
|||
/// Error returned from `BotCommand::parse` method.
|
||||
#[derive(Debug)]
|
||||
pub enum ParseError {
|
||||
/// This error was returned when count of arguments will be less than expected count.
|
||||
/// This error was returned when count of arguments will be less than
|
||||
/// expected count.
|
||||
TooFewArguments { expected: usize, found: usize, message: String },
|
||||
/// This error was returned when count of arguments will be greater than expected count.
|
||||
/// This error was returned when count of arguments will be greater than
|
||||
/// expected count.
|
||||
TooManyArguments { expected: usize, found: usize, message: String },
|
||||
/// This error was returned when error from `FromStr::from_str` was occured.
|
||||
/// This error was returned when error from `FromStr::from_str` was
|
||||
/// occured.
|
||||
IncorrectFormat,
|
||||
/// This error was returned when input command does not represent in list of commands.
|
||||
/// This error was returned when input command does not represent in list
|
||||
/// of commands.
|
||||
UnknownCommand(String),
|
||||
/// This error was returned when command bot name is different from expected bot name.
|
||||
/// This error was returned when command bot name is different from
|
||||
/// expected bot name.
|
||||
WrongBotName(String),
|
||||
/// Custom error which you can return from custom parser.
|
||||
Custom(String),
|
||||
|
@ -282,177 +295,4 @@ mod tests {
|
|||
let actual = parse_command(data, "");
|
||||
assert_eq!(actual, expected)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_command_with_args() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
Start(String),
|
||||
Help,
|
||||
}
|
||||
|
||||
let data = "/start arg1 arg2";
|
||||
let expected = DefaultCommands::Start("arg1 arg2".to_string());
|
||||
let actual = DefaultCommands::parse(data, "").unwrap();
|
||||
assert_eq!(actual, expected)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attribute_prefix() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
#[command(prefix = "!")]
|
||||
Start(String),
|
||||
Help,
|
||||
}
|
||||
|
||||
let data = "!start arg1 arg2";
|
||||
let expected = DefaultCommands::Start("arg1 arg2".to_string());
|
||||
let actual = DefaultCommands::parse(data, "").unwrap();
|
||||
assert_eq!(actual, expected)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn many_attributes() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
#[command(prefix = "!", description = "desc")]
|
||||
Start,
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start,
|
||||
DefaultCommands::parse("!start", "").unwrap()
|
||||
);
|
||||
assert_eq!(DefaultCommands::descriptions(), "!start - desc\n/help\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_attributes() {
|
||||
#[command(
|
||||
prefix = "!",
|
||||
rename = "lowercase",
|
||||
description = "Bot commands"
|
||||
)]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
#[command(prefix = "/")]
|
||||
Start,
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start,
|
||||
DefaultCommands::parse("/start", "MyNameBot").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
DefaultCommands::Help,
|
||||
DefaultCommands::parse("!help", "MyNameBot").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
DefaultCommands::descriptions(),
|
||||
"Bot commands\n/start\n!help\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_command_with_bot_name() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
#[command(prefix = "/")]
|
||||
Start,
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start,
|
||||
DefaultCommands::parse("/start@MyNameBot", "MyNameBot").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_with_split() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[command(parse_with = "split")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
Start(u8, String),
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start(10, "hello".to_string()),
|
||||
DefaultCommands::parse("/start 10 hello", "").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_with_split2() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[command(parse_with = "split", separator = "|")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
Start(u8, String),
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start(10, "hello".to_string()),
|
||||
DefaultCommands::parse("/start 10|hello", "").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_custom_parser() {
|
||||
fn custom_parse_function(
|
||||
s: String,
|
||||
) -> Result<(u8, String), ParseError> {
|
||||
let vec = s.split_whitespace().collect::<Vec<_>>();
|
||||
let (left, right) = match vec.as_slice() {
|
||||
[l, r] => (l, r),
|
||||
_ => return Err(ParseError::IncorrectFormat),
|
||||
};
|
||||
left.parse::<u8>().map(|res| (res, right.to_string())).map_err(
|
||||
|_| {
|
||||
ParseError::Custom(
|
||||
"First argument must be a integer!".to_owned(),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[command(rename = "lowercase")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
#[command(parse_with = "custom_parse_function")]
|
||||
Start(u8, String),
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start(10, "hello".to_string()),
|
||||
DefaultCommands::parse("/start 10 hello", "").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_named_fields() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[command(parse_with = "split")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
Start { num: u8, data: String },
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start { num: 10, data: "hello".to_string() },
|
||||
DefaultCommands::parse("/start 10 hello", "").unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
167
tests/command.rs
Normal file
167
tests/command.rs
Normal file
|
@ -0,0 +1,167 @@
|
|||
use teloxide::utils::command::{BotCommand, ParseError};
|
||||
|
||||
// We put tests here because macro expand in unit tests in module teloxide::utils::command
|
||||
// was a failure
|
||||
|
||||
#[test]
|
||||
fn parse_command_with_args() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
Start(String),
|
||||
Help,
|
||||
}
|
||||
|
||||
let data = "/start arg1 arg2";
|
||||
let expected = DefaultCommands::Start("arg1 arg2".to_string());
|
||||
let actual = DefaultCommands::parse(data, "").unwrap();
|
||||
assert_eq!(actual, expected)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attribute_prefix() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
#[command(prefix = "!")]
|
||||
Start(String),
|
||||
Help,
|
||||
}
|
||||
|
||||
let data = "!start arg1 arg2";
|
||||
let expected = DefaultCommands::Start("arg1 arg2".to_string());
|
||||
let actual = DefaultCommands::parse(data, "").unwrap();
|
||||
assert_eq!(actual, expected)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn many_attributes() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
#[command(prefix = "!", description = "desc")]
|
||||
Start,
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start,
|
||||
DefaultCommands::parse("!start", "").unwrap()
|
||||
);
|
||||
assert_eq!(DefaultCommands::descriptions(), "!start - desc\n/help\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_attributes() {
|
||||
#[command(prefix = "!", rename = "lowercase", description = "Bot commands")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
#[command(prefix = "/")]
|
||||
Start,
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start,
|
||||
DefaultCommands::parse("/start", "MyNameBot").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
DefaultCommands::Help,
|
||||
DefaultCommands::parse("!help", "MyNameBot").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
DefaultCommands::descriptions(),
|
||||
"Bot commands\n/start\n!help\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_command_with_bot_name() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
#[command(prefix = "/")]
|
||||
Start,
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start,
|
||||
DefaultCommands::parse("/start@MyNameBot", "MyNameBot").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_with_split() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[command(parse_with = "split")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
Start(u8, String),
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start(10, "hello".to_string()),
|
||||
DefaultCommands::parse("/start 10 hello", "").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_with_split2() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[command(parse_with = "split", separator = "|")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
Start(u8, String),
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start(10, "hello".to_string()),
|
||||
DefaultCommands::parse("/start 10|hello", "").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_custom_parser() {
|
||||
fn custom_parse_function(s: String) -> Result<(u8, String), ParseError> {
|
||||
let vec = s.split_whitespace().collect::<Vec<_>>();
|
||||
let (left, right) = match vec.as_slice() {
|
||||
[l, r] => (l, r),
|
||||
_ => return Err(ParseError::IncorrectFormat),
|
||||
};
|
||||
left.parse::<u8>().map(|res| (res, right.to_string())).map_err(|_| {
|
||||
ParseError::Custom("First argument must be a integer!".to_owned())
|
||||
})
|
||||
}
|
||||
|
||||
#[command(rename = "lowercase")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
#[command(parse_with = "custom_parse_function")]
|
||||
Start(u8, String),
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start(10, "hello".to_string()),
|
||||
DefaultCommands::parse("/start 10 hello", "").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_named_fields() {
|
||||
#[command(rename = "lowercase")]
|
||||
#[command(parse_with = "split")]
|
||||
#[derive(BotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
Start { num: u8, data: String },
|
||||
Help,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
DefaultCommands::Start { num: 10, data: "hello".to_string() },
|
||||
DefaultCommands::parse("/start 10 hello", "").unwrap()
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue