#[cfg(test)]
use std::str::FromStr;
use crate::Promptor;
#[derive(Debug, PartialEq)]
struct RGB {
r: u8,
g: u8,
b: u8,
}
impl FromStr for RGB {
type Err = std::num::ParseIntError;
fn from_str(hex_code: &str) -> Result<Self, Self::Err> {
let r: u8 = u8::from_str_radix(&hex_code[1..3], 16)?;
let g: u8 = u8::from_str_radix(&hex_code[3..5], 16)?;
let b: u8 = u8::from_str_radix(&hex_code[5..7], 16)?;
Ok(RGB { r, g, b })
}
}
#[test]
fn sanity_checks() {
let input = b"";
let mut output = Vec::new();
let mut promptor = Promptor {
reader: &input[..],
writer: &mut output,
};
assert_eq!("32".parse::<i32>().unwrap(), i32::from_str("32").unwrap());
assert!(promptor.read::<i32>("32").is_some());
assert!(promptor
.read::<i32>("56 fdfs θ gx二éfs sdf34ごν53 df3dfsd2")
.is_none());
assert!(promptor.read::<f32>("32").is_some());
assert!(promptor.read::<i32>("32.32").is_none());
}
#[test]
fn composite_type_checks() {
let input = b"";
let mut output = Vec::new();
let mut promptor = Promptor {
reader: &input[..],
writer: &mut output,
};
let call_through_trait = RGB::from_str(r"#fa7268").unwrap()
== RGB {
r: 250,
g: 114,
b: 104,
};
let call_through_maybe = promptor.read::<RGB>(r"#fa7268").unwrap()
== RGB {
r: 250,
g: 114,
b: 104,
};
assert_eq!(call_through_trait, call_through_maybe);
assert!(promptor.read::<RGB>(r"gkhgkjyfa7jhkhjk268").is_none());
}
#[test]
fn chaining_checks() {
let input = b"";
let mut output = Vec::new();
let mut promptor = Promptor {
reader: &input[..],
writer: &mut output,
};
let res = promptor.read::<i32>("32").map(|x| x * 2).unwrap_or_default();
assert_eq!(res, 64);
let res = promptor
.read::<f32>("3.14")
.map(|x| x * 2f32)
.unwrap_or_default();
assert_eq!(res, 6.28);
let res = promptor
.read::<RGB>(r"#fa7268")
.map(|rgb| rgb.r - 100)
.unwrap_or_default();
assert_eq!(res, 150);
let res = promptor
.read::<i32>("3fdgdf2")
.map(|x| x * 2)
.unwrap_or_default();
assert_eq!(res, 0);
}
#[test]
fn stdio_good_input_check() {
let input = b"32";
let mut output = Vec::new();
let mut promptor = Promptor {
reader: &input[..],
writer: &mut output,
};
let res = promptor
.input::<i32>("What's your favourite number? ")
.unwrap();
let output = String::from_utf8(output).unwrap();
assert_eq!("What's your favourite number? ", output);
assert_eq!(32, res);
}
#[test]
fn stdio_bad_input_check() {
let input = b"gdfg32";
let mut output = Vec::new();
let mut promptor = Promptor {
reader: &input[..],
writer: &mut output,
};
let res = promptor.input::<i32>("What's your favourite number? ");
let output = String::from_utf8(output).unwrap();
assert_eq!("What's your favourite number? ", output);
assert!(res.is_none());
}
#[test]
fn stdio_good_prompt_check() {
let input = b"32";
let mut output = Vec::new();
let mut promptor = Promptor {
reader: &input[..],
writer: &mut output,
};
let res: i32 = promptor.prompt("Please enter a number between 1 and 50: ", |x| {
1 <= x && x <= 50
});
let output = String::from_utf8(output).unwrap();
assert_eq!("Please enter a number between 1 and 50: ", output);
assert_eq!(32, res);
}
#[test]
fn stdio_bad_prompt_check() {
let input = b"3ghhj2\n25";
let mut output = Vec::new();
let mut promptor = Promptor {
reader: &input[..],
writer: &mut output,
};
let res: i32 = promptor.prompt("Please enter a number between 1 and 50: ", |x| {
1 <= x && x <= 50
});
let output = String::from_utf8(output).unwrap();
assert_eq!("Please enter a number between 1 and 50: Invalid input! Please try again.\nPlease enter a number between 1 and 50: ", output);
assert_eq!(25, res);
}