Add tests and an example

This commit is contained in:
Alexander Bantyev 2020-09-17 00:19:02 +03:00
parent 625e2355b9
commit 640e6dd6bf
Signed by: balsoft
GPG Key ID: E081FF12ADCB4AD5
3 changed files with 177 additions and 9 deletions

View File

@ -11,7 +11,7 @@ use std::time::Duration;
use osd::notify::{OSD, Urgency};
use osd::config::Config;
#[derive(Debug)]
#[derive(Debug, Eq, PartialEq)]
enum Threshold {
Percentage(i32),
Minutes(i32)
@ -25,18 +25,133 @@ enum State {
Normal
}
fn threshold_sane(thresh: Threshold) -> Option<Threshold> {
match thresh {
Threshold::Percentage(p) => {
if p < 0 || p > 100 { return None; }
Some(thresh)
},
Threshold::Minutes(m) => {
if m < 0 { return None; }
Some(thresh)
}
}
}
fn parse_threshold(thresh: String) -> Option<Threshold> {
let mut s = thresh.clone();
let last = s.pop();
let parsed = s.parse();
match last {
Some('%') => s.parse().map(Threshold::Percentage).ok(),
Some('m') => s.parse().map(Threshold::Minutes).ok(),
Some('%') => parsed.map(Threshold::Percentage).ok().and_then(threshold_sane),
Some('m') => parsed.map(Threshold::Minutes).ok().and_then(threshold_sane),
_ => None
}
}
#[cfg(test)]
mod parse_threshold_tests {
use super::parse_threshold;
use super::Threshold;
#[test]
fn parses_percentage() {
assert_eq!(parse_threshold("15%".to_string()), Some(Threshold::Percentage(15)));
}
#[test]
fn parses_minutes() {
assert_eq!(parse_threshold("10m".to_string()), Some(Threshold::Minutes(10)));
}
#[test]
fn fails_on_incorrect_percentage() {
assert_eq!(parse_threshold("foo%".to_string()), None);
}
#[test]
fn fails_on_incorrect_minutes() {
assert_eq!(parse_threshold("foom".to_string()), None);
}
#[test]
fn fails_on_high_percentage() {
assert_eq!(parse_threshold("110%".to_string()), None);
}
#[test]
fn fails_on_negative_percentage() {
assert_eq!(parse_threshold("-10%".to_string()), None);
}
#[test]
fn fails_on_negative_minutes() {
assert_eq!(parse_threshold("-10m".to_string()), None);
}
}
fn format_duration(duration: f32) -> String {
let mut d = duration as i32;
if d == 0 {
return "0s".to_string();
}
let mut s = String::new();
if d < 0 {
s.push_str("-");
d = -d;
}
let hours = d / 3600;
let minutes = (d % 3600) / 60;
let seconds = d % 60;
if hours > 0 {
s.push_str(&format!("{}h", hours));
}
if minutes > 0 {
if hours > 0 { s.push_str(" "); }
s.push_str(&format!("{}m", minutes));
}
if seconds > 0 {
if hours > 0 || minutes > 0 { s.push_str(" "); }
s.push_str(&format!("{}s", seconds));
}
s
}
#[cfg(test)]
mod format_duration_tests {
use super::format_duration;
#[test]
fn no_time() {
assert_eq!(&format_duration(0.), "0s");
}
#[test]
fn seconds() {
assert_eq!(&format_duration(12.), "12s");
}
#[test]
fn minutes_seconds() {
assert_eq!(&format_duration(123.), "2m 3s");
}
#[test]
fn minutes() {
assert_eq!(&format_duration(120.), "2m");
}
#[test]
fn hours_minutes_seconds() {
assert_eq!(&format_duration(12345.), "3h 25m 45s");
}
#[test]
fn hours_minutes() {
assert_eq!(&format_duration(9000.), "2h 30m")
}
#[test]
fn hours() {
assert_eq!(&format_duration(3600.), "1h")
}
#[test]
fn negative() {
assert_eq!(&format_duration(-12345.), "-3h 25m 45s");
}
}
fn main() -> battery::Result<()> {
let mut config = Config::new("battery");
@ -48,8 +163,6 @@ fn main() -> battery::Result<()> {
let refresh_interval = config.get_default("default", "refresh interval", 30);
println!("{:?}, {:?}", low_threshold, critical_threshold);
let mut osd = OSD::new();
osd.icon = Some(String::from("battery"));
@ -69,6 +182,7 @@ fn main() -> battery::Result<()> {
let mut state: State;
let mut last_state: State = State::Normal;
loop {
state = match battery.state() {
battery::State::Charging => State::Charging,
@ -92,14 +206,14 @@ fn main() -> battery::Result<()> {
match state {
State::Charging => {
battery.time_to_full().map(|ttf| {
osd.title = Some(format!("Charging, {:?} until full", ttf));
osd.title = Some(format!("Charging, {} until full", format_duration(ttf.value)));
osd.urgency = Urgency::Low;
osd.update();
});
}
State::Low => {
battery.time_to_empty().map(|tte| {
osd.title = Some(format!("Low battery, {:?} remaining", tte));
osd.title = Some(format!("Low battery, {} remaining", format_duration(tte.value)));
osd.urgency = Urgency::Normal;
osd.update();
});
@ -110,7 +224,7 @@ fn main() -> battery::Result<()> {
if state == State::Critical {
battery.time_to_empty().map(|tte| {
osd.title = Some(format!("Critically low battery, {:?} remaining", tte));
osd.title = Some(format!("Critically low battery, {} remaining", format_duration(tte.value)));
osd.urgency = Urgency::Critical;
osd.update();
});

54
common/examples/simple.rs Normal file
View File

@ -0,0 +1,54 @@
extern crate simple_osd_common as osd;
use osd::notify::{OSD, OSDContents, OSDProgressText, Urgency};
use osd::config::Config;
use std::time::Duration;
use std::thread::sleep;
fn main() {
let mut config = Config::new("simple-example");
let foo = config.get_default("example section", "foo", "bar baz".to_string());
println!("Value of foo is {}", foo);
let example_no_default = config.get::<i32>("example section", "example variable with no default");
println!("Value of example variable with no default is {:?}", example_no_default);
let refresh_interval = config.get_default("default", "refresh interval", 1);
let mut osd_simple = OSD::new();
osd_simple.title = Some("Simple (but urgent) notification".to_string());
osd_simple.contents = OSDContents::Simple(Some("Just simple contents".to_string()));
osd_simple.urgency = Urgency::Critical;
let mut percentage = 0.;
let mut osd_progress_bar_percentage = OSD::new();
osd_progress_bar_percentage.title = Some("A progress bar showing important percentage!".to_string());
let eta = 15.;
let mut elapsed = 0.;
let mut osd_progress_bar_text = OSD::new();
osd_progress_bar_text.title = Some("Nuclear warhead launch in progress, time left:".to_string());
osd_progress_bar_text.urgency = Urgency::Low;
loop {
percentage = (percentage + 0.123) % 1.;
elapsed = (elapsed + refresh_interval as f32) % eta;
osd_progress_bar_percentage.contents = OSDContents::Progress(percentage, OSDProgressText::Percentage);
osd_progress_bar_text.contents = OSDContents::Progress(elapsed / eta, OSDProgressText::Text(Some(format!("{}s / {}s", elapsed, eta))));
osd_simple.update();
osd_progress_bar_percentage.update();
osd_progress_bar_text.update();
sleep(Duration::from_secs(refresh_interval));
}
}