diff --git a/crates/atuin-client/Cargo.toml b/crates/atuin-client/Cargo.toml index 02f189595c6..9887fc932ae 100644 --- a/crates/atuin-client/Cargo.toml +++ b/crates/atuin-client/Cargo.toml @@ -76,8 +76,10 @@ palette = { version = "0.7.5", features = ["serializing"] } lazy_static = "1.4.0" strum_macros = "0.26.3" strum = { version = "0.26.2", features = ["strum_macros"] } +tracing.workspace = true [dev-dependencies] tokio = { version = "1", features = ["full"] } pretty_assertions = { workspace = true } testing_logger = "0.1.1" +tracing-test = "0.2.5" diff --git a/crates/atuin-client/src/theme.rs b/crates/atuin-client/src/theme.rs index 9ebe6f9cfe1..d83d1ba2474 100644 --- a/crates/atuin-client/src/theme.rs +++ b/crates/atuin-client/src/theme.rs @@ -1,6 +1,8 @@ use config::{Config, File as ConfigFile, FileFormat}; use lazy_static::lazy_static; use log; +use tracing; +use tracing::instrument; use palette::named; use serde::{Deserialize, Serialize}; use serde_json; @@ -55,6 +57,7 @@ use crossterm::style::{Color, ContentStyle}; // For now, a theme is loaded as a mapping of meanings to colors, but it may be desirable to // expand that in the future to general styles, so we populate a Meaning->ContentStyle hashmap. +#[derive(Debug)] pub struct Theme { pub name: String, pub parent: Option, @@ -120,6 +123,7 @@ impl Theme { // but we do not have this on in general, as it could print unfiltered text to the terminal // from a theme TOML file. However, it will always return a theme, falling back to // defaults on error, so that a TOML file does not break loading + #[instrument(skip(debug))] pub fn from_foreground_colors( name: String, parent: Option<&Theme>, @@ -133,7 +137,7 @@ impl Theme { *name, StyleFactory::from_fg_string(color).unwrap_or_else(|err| { if debug { - log::warn!( + tracing::warn!( "Tried to load string as a color unsuccessfully: ({}={}) {}", name, color, @@ -340,6 +344,7 @@ lazy_static! { } // To avoid themes being repeatedly loaded, we store them in a theme manager +#[derive(Debug)] pub struct ThemeManager { loaded_themes: HashMap, debug: bool, @@ -434,7 +439,7 @@ impl ThemeManager { }; if debug && name != theme_config.theme.name { - log::warn!( + tracing::warn!( "Your theme config name is not the name of your loaded theme {} != {}", name, theme_config.theme.name @@ -450,6 +455,7 @@ impl ThemeManager { // Check if the requested theme is loaded and, if not, then attempt to get it // from the builtins or, if not there, from file + #[instrument(skip(self))] pub fn load_theme(&mut self, name: &str, max_depth: Option) -> &Theme { if self.loaded_themes.contains_key(name) { return self.loaded_themes.get(name).unwrap(); @@ -460,7 +466,7 @@ impl ThemeManager { None => match self.load_theme_from_file(name, max_depth.unwrap_or(DEFAULT_MAX_DEPTH)) { Ok(theme) => theme, Err(err) => { - log::warn!("Could not load theme {}: {}", name, err); + tracing::warn!("Could not load theme {}: {}", name, err); built_ins.get("default").unwrap() } }, @@ -471,6 +477,7 @@ impl ThemeManager { #[cfg(test)] mod theme_tests { use super::*; + use tracing_test::traced_test; #[test] fn test_can_load_builtin_theme() { @@ -601,9 +608,8 @@ mod theme_tests { } #[test] + #[traced_test] fn test_can_use_parent_theme_for_fallbacks() { - testing_logger::setup(); - let mut manager = ThemeManager::new(Some(false), Some("".to_string())); // First, we introduce a base theme @@ -667,8 +673,6 @@ mod theme_tests { from_string("white").ok() ); - testing_logger::validate(|captured_logs| assert_eq!(captured_logs.len(), 0)); - // If the parent is not found, we end up with the base theme colors let nunsolarized = Config::builder() .add_source(ConfigFile::from_str( @@ -695,55 +699,51 @@ mod theme_tests { Some(Color::DarkBlue) ); - testing_logger::validate(|captured_logs| { + logs_assert(|captured_logs: &[&str]| { + // More context lines with tracing than just the logline itself. assert_eq!(captured_logs.len(), 1); - assert_eq!(captured_logs[0].body, + assert!(captured_logs[0].contains( "Could not load theme nonsolarized: Empty theme directory override and could not find theme elsewhere" - ); - assert_eq!(captured_logs[0].level, log::Level::Warn) + )); + assert!(captured_logs[0].contains("WARN")); + Ok(()) }); } #[test] + #[traced_test] fn test_can_debug_theme() { - testing_logger::setup(); - [true, false].iter().for_each(|debug| { - let mut manager = ThemeManager::new(Some(*debug), Some("".to_string())); - let config = Config::builder() - .add_source(ConfigFile::from_str( - " - [theme] - name = \"mytheme\" - - [colors] - Guidance = \"white\" - AlertInfo = \"xinetic\" - ", - FileFormat::Toml, - )) - .build() - .unwrap(); - manager - .load_theme_from_config("config_theme", config, 1) - .unwrap(); - testing_logger::validate(|captured_logs| { - if *debug { - assert_eq!(captured_logs.len(), 2); - assert_eq!( - captured_logs[0].body, - "Your theme config name is not the name of your loaded theme config_theme != mytheme" - ); - assert_eq!(captured_logs[0].level, log::Level::Warn); - assert_eq!( - captured_logs[1].body, - "Tried to load string as a color unsuccessfully: (AlertInfo=xinetic) No such color in palette" - ); - assert_eq!(captured_logs[1].level, log::Level::Warn) - } else { - assert_eq!(captured_logs.len(), 0) - } - }) - }) + let debug = true; + let mut manager = ThemeManager::new(Some(debug), Some("".to_string())); + let config = Config::builder() + .add_source(ConfigFile::from_str( + " + [theme] + name = \"mytheme\" + + [colors] + Guidance = \"white\" + AlertInfo = \"xinetic\" + ", + FileFormat::Toml, + )) + .build() + .unwrap(); + manager + .load_theme_from_config("config_theme", config, 1) + .unwrap(); + logs_assert(|captured_logs: &[&str]| { + // More context lines with tracing than just the logline itself. + assert_eq!(captured_logs.len(), 2); + assert!(captured_logs[0].contains( + "Your theme config name is not the name of your loaded theme config_theme != mytheme" + )); + assert!(captured_logs[1].contains( + "Tried to load string as a color unsuccessfully: (AlertInfo=xinetic) No such color in palette" + )); + assert!(captured_logs.into_iter().all(|line| line.contains("WARN"))); + Ok(()) + }); } #[test]