Moving logic to current_weather_printer for better testing

This commit is contained in:
Jorge Bolois 2023-05-26 20:21:28 +02:00
parent 0dd0f5ab49
commit dbcf9437b6
3 changed files with 205 additions and 69 deletions

View File

@ -0,0 +1,34 @@
pub struct CurrentWeatherPrintParams {
pub all: bool,
pub is_day: bool,
pub temperature: bool,
pub windspeed: bool,
pub winddirection: bool,
pub include_coords: bool,
pub include_city: bool,
pub clean: bool,
}
impl CurrentWeatherPrintParams {
pub fn new(
all: bool,
is_day: bool,
temperature: bool,
windspeed: bool,
winddirection: bool,
include_coords: bool,
include_city: bool,
clean: bool,
) -> CurrentWeatherPrintParams {
CurrentWeatherPrintParams {
all,
is_day,
temperature,
windspeed,
winddirection,
include_coords,
include_city,
clean,
}
}
}

View File

@ -1,18 +1,84 @@
use crate::current_weather::CurrentWeather;
use crate::{
coords::Coordinates, current_weater_print_params::CurrentWeatherPrintParams,
current_weather::CurrentWeather,
};
pub struct CurrentWeatherPrinter {
current_weather: CurrentWeather,
clean: bool,
params: CurrentWeatherPrintParams,
coords: Coordinates,
city: Option<String>,
}
impl CurrentWeatherPrinter {
pub fn new(current_weather: CurrentWeather, clean: bool) -> CurrentWeatherPrinter {
pub fn new(
current_weather: CurrentWeather,
params: CurrentWeatherPrintParams,
coords: Coordinates,
city: Option<String>,
) -> CurrentWeatherPrinter {
CurrentWeatherPrinter {
current_weather,
clean,
params,
coords,
city,
}
}
pub fn extract_day(&self) -> String {
pub fn extract_string(&self) -> String {
let mut string_vec: Vec<String> = Vec::new();
if !self.params.clean {
let mut title_header: Vec<String> = Vec::new();
title_header.push(String::from("=== Current weather"));
if (self.params.all || self.params.include_city) && self.city.is_some() {
title_header.push(String::from("for"));
title_header.push(self.city.clone().unwrap());
}
title_header.push(String::from("==="));
string_vec.push(title_header.join(" "));
} else {
if self.params.all || self.params.include_coords {
string_vec.push(self.coords.latitude.to_string());
string_vec.push(self.coords.longitude.to_string());
}
if (self.params.all || self.params.include_city) && self.city.is_some() {
string_vec.push(self.city.clone().unwrap());
}
}
if self.params.is_day || self.params.all {
string_vec.push(self.extract_day());
}
if self.params.temperature || self.params.all {
string_vec.push(self.extract_temperature());
}
if self.params.windspeed || self.params.all {
string_vec.push(self.extract_wind_speed());
}
if self.params.winddirection || self.params.all {
string_vec.push(self.extract_wind_direction());
}
if !self.params.clean && (self.params.all || self.params.include_coords) {
string_vec.push(format!(
"Latitude: {}, Longitude: {}",
self.coords.latitude, self.coords.longitude
));
}
if self.params.clean {
let final_string = string_vec.join(",");
final_string
} else {
string_vec.push(String::from("=== Weather data by Open-Meteo.com ==="));
string_vec.join("\n")
}
}
fn extract_day(&self) -> String {
if self.current_weather.is_day == 1 {
self.parse_custom_data(&self.current_weather.is_day.to_string(), "Day")
} else {
@ -20,7 +86,7 @@ impl CurrentWeatherPrinter {
}
}
pub fn extract_temperature(&self) -> String {
fn extract_temperature(&self) -> String {
self.parse_simple_data(
&self.current_weather.temperature.to_string(),
"Temperature",
@ -28,7 +94,7 @@ impl CurrentWeatherPrinter {
)
}
pub fn extract_wind_speed(&self) -> String {
fn extract_wind_speed(&self) -> String {
self.parse_simple_data(
&self.current_weather.windspeed.to_string(),
"Wind speed",
@ -36,7 +102,7 @@ impl CurrentWeatherPrinter {
)
}
pub fn extract_wind_direction(&self) -> String {
fn extract_wind_direction(&self) -> String {
self.parse_simple_data(
&self.current_weather.winddirection.to_string(),
"Wind direction",
@ -45,7 +111,7 @@ impl CurrentWeatherPrinter {
}
fn parse_custom_data(&self, data: &str, custom: &str) -> String {
if self.clean {
if self.params.clean {
format!("{data}")
} else {
format!("{custom}")
@ -53,7 +119,7 @@ impl CurrentWeatherPrinter {
}
fn parse_simple_data(&self, data: &str, descriptor: &str, end_text: Option<&str>) -> String {
if self.clean {
if self.params.clean {
format!("{data}")
} else {
let end_text = end_text.unwrap_or("");
@ -67,19 +133,45 @@ mod tests {
use super::*;
#[test]
fn clean_data() {
fn clean_all_data() {
let current_weather = CurrentWeather {
is_day: 1,
temperature: 12.5,
windspeed: 7.0,
winddirection: 90.0,
};
let printer = CurrentWeatherPrinter::new(current_weather, true);
let params =
CurrentWeatherPrintParams::new(true, false, false, false, false, false, false, true);
let coords = Coordinates::new(5.0, -5.0);
let printer = CurrentWeatherPrinter::new(
current_weather,
params,
coords,
Some(String::from("TestCity")),
);
assert_eq!(printer.extract_day(), "1");
assert_eq!(printer.extract_temperature(), "12.5");
assert_eq!(printer.extract_wind_speed(), "7");
assert_eq!(printer.extract_wind_direction(), "90");
assert_eq!(printer.extract_string(), "5,-5,TestCity,1,12.5,7,90");
}
#[test]
fn clean_basic_data() {
let current_weather = CurrentWeather {
is_day: 1,
temperature: 15.5,
windspeed: 12.2,
winddirection: 150.0,
};
let params =
CurrentWeatherPrintParams::new(false, true, true, true, false, false, false, true);
let coords = Coordinates::new(12.0, -55.0);
let printer = CurrentWeatherPrinter::new(
current_weather,
params,
coords,
Some(String::from("TestCity")),
);
assert_eq!(printer.extract_string(), "1,15.5,12.2");
}
#[test]
@ -90,11 +182,53 @@ mod tests {
windspeed: 15.5,
winddirection: 118.0,
};
let printer = CurrentWeatherPrinter::new(current_weather, false);
let params =
CurrentWeatherPrintParams::new(true, false, false, false, false, false, false, false);
let coords = Coordinates::new(5.0, -5.0);
let printer = CurrentWeatherPrinter::new(
current_weather,
params,
coords,
Some(String::from("TestCity")),
);
assert_eq!(printer.extract_day(), "Night");
assert_eq!(printer.extract_temperature(), "Temperature: 22°C");
assert_eq!(printer.extract_wind_speed(), "Wind speed: 15.5 km/h");
assert_eq!(printer.extract_wind_direction(), "Wind direction: 118°");
let output = printer.extract_string();
assert!(output.contains("Night"));
assert!(output.contains("Temperature: 22°C"));
assert!(output.contains("Wind speed: 15.5 km/h"));
assert!(output.contains("Wind direction: 118°"));
assert!(output.contains("Latitude: 5"));
assert!(output.contains("Longitude: -5"));
assert!(output.contains("TestCity"));
assert!(output.contains("Open-Meteo.com"));
}
#[test]
fn full_basic_data() {
let current_weather = CurrentWeather {
is_day: 1,
temperature: 3.0,
windspeed: 22.5,
winddirection: 125.0,
};
let params =
CurrentWeatherPrintParams::new(false, true, true, true, false, false, false, false);
let coords = Coordinates::new(12.15, 0.235);
let printer = CurrentWeatherPrinter::new(
current_weather,
params,
coords,
Some(String::from("NoCity")),
);
let output = printer.extract_string();
assert!(output.contains("Day"));
assert!(output.contains("Temperature: 3°C"));
assert!(output.contains("Wind speed: 22.5 km/h"));
assert!(!output.contains("Wind direction: 125°"));
assert!(!output.contains("Latitude: 12.15"));
assert!(!output.contains("Longitude: 0.235"));
assert!(!output.contains("Nocity"));
assert!(output.contains("Open-Meteo.com"));
}
}

View File

@ -1,6 +1,7 @@
mod cli;
mod coords;
mod current_weater_print_params;
mod current_weather;
mod current_weather_printer;
mod ifconfig;
@ -8,6 +9,7 @@ mod ip_api;
mod open_meteo;
use billboard::{Alignment, Billboard};
use current_weater_print_params::CurrentWeatherPrintParams;
use std::process::exit;
use structopt::StructOpt;
@ -91,61 +93,27 @@ fn main() {
exit(1);
});
let mut string_vec: Vec<String> = Vec::new();
if !clean {
let mut title_header: Vec<String> = Vec::new();
title_header.push(String::from("=== Current weather"));
if (all || include_city) && city.is_some() {
title_header.push(String::from("for"));
title_header.push(city.unwrap());
}
title_header.push(String::from("==="));
string_vec.push(title_header.join(" "));
} else {
if all || include_coords {
string_vec.push(coordinates.latitude.to_string());
string_vec.push(coordinates.longitude.to_string());
}
if (all || include_city) && city.is_some() {
string_vec.push(city.unwrap());
}
}
let current_weather_printer = CurrentWeatherPrinter::new(current_weather, clean);
if is_day || all {
string_vec.push(current_weather_printer.extract_day());
}
if temperature || all {
string_vec.push(current_weather_printer.extract_temperature());
}
if windspeed || all {
string_vec.push(current_weather_printer.extract_wind_speed());
}
if winddirection || all {
string_vec.push(current_weather_printer.extract_wind_direction());
}
if !clean && (all || include_coords) {
string_vec.push(format!(
"Latitude: {}, Longitude: {}",
coordinates.latitude, coordinates.longitude
));
}
let print_params = CurrentWeatherPrintParams::new(
all,
is_day,
temperature,
windspeed,
winddirection,
include_coords,
include_city,
clean,
);
let current_weather_printer = CurrentWeatherPrinter::new(current_weather, print_params, coordinates, city);
let output = current_weather_printer.extract_string();
if clean {
let final_string = string_vec.join(",");
println!("{final_string}");
println!("{output}");
} else {
string_vec.push(String::from("=== Weather data by Open-Meteo.com ==="));
let final_string = string_vec.join("\n");
Billboard::builder()
.text_alignment(Alignment::Left)
.box_alignment(Alignment::Left)
.build()
.eprint(final_string);
.eprint(output);
}
}
}