mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add tests for Color::parse
This commit is contained in:
parent
45a9d54801
commit
29f85a4398
@ -155,14 +155,14 @@ impl Color {
|
|||||||
/// * `"#123456"` becomes `Color::Rgb(0x12, 0x34, 0x56)`
|
/// * `"#123456"` becomes `Color::Rgb(0x12, 0x34, 0x56)`
|
||||||
pub fn parse(value: &str) -> Option<Self> {
|
pub fn parse(value: &str) -> Option<Self> {
|
||||||
Some(match value {
|
Some(match value {
|
||||||
"black" => Color::Dark(BaseColor::Black),
|
"dark black" | "black" => Color::Dark(BaseColor::Black),
|
||||||
"red" => Color::Dark(BaseColor::Red),
|
"dark red" | "red" => Color::Dark(BaseColor::Red),
|
||||||
"green" => Color::Dark(BaseColor::Green),
|
"dark green" | "green" => Color::Dark(BaseColor::Green),
|
||||||
"yellow" => Color::Dark(BaseColor::Yellow),
|
"dark yellow" | "yellow" => Color::Dark(BaseColor::Yellow),
|
||||||
"blue" => Color::Dark(BaseColor::Blue),
|
"dark blue" | "blue" => Color::Dark(BaseColor::Blue),
|
||||||
"magenta" => Color::Dark(BaseColor::Magenta),
|
"dark magenta" | "magenta" => Color::Dark(BaseColor::Magenta),
|
||||||
"cyan" => Color::Dark(BaseColor::Cyan),
|
"dark cyan" | "cyan" => Color::Dark(BaseColor::Cyan),
|
||||||
"white" => Color::Dark(BaseColor::White),
|
"dark white" | "white" => Color::Dark(BaseColor::White),
|
||||||
"light black" => Color::Light(BaseColor::Black),
|
"light black" => Color::Light(BaseColor::Black),
|
||||||
"light red" => Color::Light(BaseColor::Red),
|
"light red" => Color::Light(BaseColor::Red),
|
||||||
"light green" => Color::Light(BaseColor::Green),
|
"light green" => Color::Light(BaseColor::Green),
|
||||||
@ -172,73 +172,136 @@ impl Color {
|
|||||||
"light cyan" => Color::Light(BaseColor::Cyan),
|
"light cyan" => Color::Light(BaseColor::Cyan),
|
||||||
"light white" => Color::Light(BaseColor::White),
|
"light white" => Color::Light(BaseColor::White),
|
||||||
"default" => Color::TerminalDefault,
|
"default" => Color::TerminalDefault,
|
||||||
value => return Color::parse_special(value),
|
value => {
|
||||||
|
return parse_special(value).or_else(|| {
|
||||||
|
log::warn!("Could not parse color `{}`.", value);
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_special(value: &str) -> Option<Color> {
|
fn parse_special(value: &str) -> Option<Color> {
|
||||||
if value.starts_with('#') {
|
if value.starts_with('#') {
|
||||||
let value = &value[1..];
|
parse_hex(&value[1..])
|
||||||
// Compute per-color length, and amplitude
|
} else if value.starts_with("0x") {
|
||||||
let (l, multiplier) = match value.len() {
|
parse_hex(&value[2..])
|
||||||
6 => (2, 1),
|
} else if value.len() == 6 {
|
||||||
3 => (1, 17),
|
parse_hex(value)
|
||||||
_ => panic!("Cannot parse color: {}", value),
|
} else if value.len() == 3 {
|
||||||
};
|
// RGB values between 0 and 5 maybe?
|
||||||
let r = load_hex(&value[0..l]) * multiplier;
|
// Like 050 for green
|
||||||
let g = load_hex(&value[l..2 * l]) * multiplier;
|
let rgb: Vec<_> =
|
||||||
let b = load_hex(&value[2 * l..3 * l]) * multiplier;
|
value.chars().map(|c| c as i16 - '0' as i16).collect();
|
||||||
|
|
||||||
Some(Color::Rgb(r as u8, g as u8, b as u8))
|
assert_eq!(rgb.len(), 3);
|
||||||
} else if value.len() == 3 {
|
if rgb.iter().all(|&i| i >= 0 && i < 6) {
|
||||||
// RGB values between 0 and 5 maybe?
|
Some(Color::RgbLowRes(rgb[0] as u8, rgb[1] as u8, rgb[2] as u8))
|
||||||
// Like 050 for green
|
|
||||||
let rgb: Vec<_> =
|
|
||||||
value.chars().map(|c| c as i16 - '0' as i16).collect();
|
|
||||||
|
|
||||||
assert_eq!(rgb.len(), 3);
|
|
||||||
if rgb.iter().all(|&i| i >= 0 && i < 6) {
|
|
||||||
Some(Color::RgbLowRes(
|
|
||||||
rgb[0] as u8,
|
|
||||||
rgb[1] as u8,
|
|
||||||
rgb[2] as u8,
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_hex(value: &str) -> Option<Color> {
|
||||||
|
// Compute per-color length, and amplitude
|
||||||
|
let (l, multiplier) = match value.len() {
|
||||||
|
6 => (2, 1),
|
||||||
|
3 => (1, 17),
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
let r = load_hex(&value[0..l]) * multiplier;
|
||||||
|
let g = load_hex(&value[l..2 * l]) * multiplier;
|
||||||
|
let b = load_hex(&value[2 * l..3 * l]) * multiplier;
|
||||||
|
|
||||||
|
Some(Color::Rgb(r as u8, g as u8, b as u8))
|
||||||
|
}
|
||||||
|
|
||||||
/// Loads a hexadecimal code
|
/// Loads a hexadecimal code
|
||||||
fn load_hex(s: &str) -> u16 {
|
fn load_hex(s: &str) -> u16 {
|
||||||
let mut sum = 0;
|
s.chars()
|
||||||
for c in s.chars() {
|
.rev()
|
||||||
sum *= 16;
|
.filter_map(|c| {
|
||||||
sum += match c {
|
Some(match c {
|
||||||
n @ '0'..='9' => n as i16 - '0' as i16,
|
'0'..='9' => c as u16 - '0' as u16,
|
||||||
n @ 'a'..='f' => n as i16 - 'a' as i16 + 10,
|
'a'..='f' => c as u16 - 'a' as u16 + 10,
|
||||||
n @ 'A'..='F' => n as i16 - 'A' as i16 + 10,
|
'A'..='F' => c as u16 - 'A' as u16 + 10,
|
||||||
_ => 0,
|
other => {
|
||||||
};
|
log::warn!(
|
||||||
}
|
"Invalid character `{}` in hexadecimal value `{}`.",
|
||||||
|
other,
|
||||||
sum as u16
|
s
|
||||||
|
);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, c)| c * 16u16.pow(i as u32))
|
||||||
|
.sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::Color;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_256_colors() {
|
fn test_256_colors() {
|
||||||
// Make sure Color::from_256colors never panics
|
// Make sure Color::from_256colors never panics
|
||||||
use super::Color;
|
|
||||||
|
|
||||||
// TODO: use inclusive range when it gets stable
|
for i in 0..=255u8 {
|
||||||
for i in 0..256u16 {
|
Color::from_256colors(i);
|
||||||
Color::from_256colors(i as u8);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse() {
|
||||||
|
assert_eq!(Color::parse("#fff"), Some(Color::Rgb(255, 255, 255)));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Color::parse("#abcdef"),
|
||||||
|
Some(Color::Rgb(0xab, 0xcd, 0xef))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Color::parse("0xFEDCBA"),
|
||||||
|
Some(Color::Rgb(0xfe, 0xdc, 0xba))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_low_res() {
|
||||||
|
// Make sure Color::low_res always works with valid ranges.
|
||||||
|
for r in 0..=5 {
|
||||||
|
for g in 0..=5 {
|
||||||
|
for b in 0..=5 {
|
||||||
|
assert!(
|
||||||
|
Color::low_res(r, g, b).is_some(),
|
||||||
|
"Could not create lowres color {}:{}:{}",
|
||||||
|
r,
|
||||||
|
g,
|
||||||
|
b,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for r in 6..=10 {
|
||||||
|
for g in 6..=10 {
|
||||||
|
for b in 6..=10 {
|
||||||
|
assert_eq!(
|
||||||
|
Color::low_res(r, g, b),
|
||||||
|
None,
|
||||||
|
"Created invalid lowres color {}:{}:{}",
|
||||||
|
r,
|
||||||
|
g,
|
||||||
|
b,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user