diff --git a/crates/snapbox/src/action.rs b/crates/snapbox/src/assert/action.rs similarity index 100% rename from crates/snapbox/src/action.rs rename to crates/snapbox/src/assert/action.rs diff --git a/crates/snapbox/src/error.rs b/crates/snapbox/src/assert/error.rs similarity index 97% rename from crates/snapbox/src/error.rs rename to crates/snapbox/src/assert/error.rs index 19297714..16fdf832 100644 --- a/crates/snapbox/src/error.rs +++ b/crates/snapbox/src/assert/error.rs @@ -1,3 +1,5 @@ +pub type Result = std::result::Result; + #[derive(Clone, Debug)] pub struct Error { inner: String, diff --git a/crates/snapbox/src/assert.rs b/crates/snapbox/src/assert/mod.rs similarity index 97% rename from crates/snapbox/src/assert.rs rename to crates/snapbox/src/assert/mod.rs index 152ba22e..2c986c4e 100644 --- a/crates/snapbox/src/assert.rs +++ b/crates/snapbox/src/assert/mod.rs @@ -1,3 +1,6 @@ +mod action; +mod error; + #[cfg(feature = "color")] use anstream::panic; #[cfg(feature = "color")] @@ -6,9 +9,13 @@ use anstream::stderr; use std::io::stderr; use crate::filters::{Filter as _, FilterNewlines, FilterPaths, FilterRedactions}; -use crate::Action; use crate::IntoData; +pub use action::Action; +pub use action::DEFAULT_ACTION_ENV; +pub use error::Error; +pub use error::Result; + /// Snapshot assertion against a file's contents /// /// Useful for one-off assertions with the snapshot stored in a file @@ -75,7 +82,7 @@ impl Assert { expected: crate::Data, actual: crate::Data, actual_name: Option<&dyn std::fmt::Display>, - ) -> Result<(), crate::Error> { + ) -> Result<()> { if expected.source().is_none() && actual.source().is_some() { panic!("received `(actual, expected)`, expected `(expected, actual)`"); } @@ -122,7 +129,7 @@ impl Assert { expected: crate::Data, actual: crate::Data, actual_name: Option<&dyn std::fmt::Display>, - ) -> Result<(), crate::Error> { + ) -> Result<()> { let result = self.try_verify(&expected, &actual, actual_name); let Err(err) = result else { return Ok(()); @@ -149,7 +156,7 @@ impl Assert { } else { crate::report::Styled::new(String::new(), Default::default()) }; - Err(crate::Error::new(format_args!("{err}{message}"))) + Err(Error::new(format_args!("{err}{message}"))) } Action::Overwrite => { use std::io::Write; @@ -159,7 +166,7 @@ impl Assert { actual.write_to(source).unwrap(); Ok(()) } else { - Err(crate::Error::new(format_args!("{err}"))) + Err(Error::new(format_args!("{err}"))) } } } @@ -170,7 +177,7 @@ impl Assert { expected: &crate::Data, actual: &crate::Data, actual_name: Option<&dyn std::fmt::Display>, - ) -> crate::Result<()> { + ) -> Result<()> { if expected != actual { let mut buf = String::new(); crate::report::write_diff( diff --git a/crates/snapbox/src/cmd.rs b/crates/snapbox/src/cmd.rs index 7dd26ed6..201d2402 100644 --- a/crates/snapbox/src/cmd.rs +++ b/crates/snapbox/src/cmd.rs @@ -23,7 +23,7 @@ impl Command { stdin: None, timeout: None, _stderr_to_stdout: false, - config: crate::Assert::new().action_env(crate::DEFAULT_ACTION_ENV), + config: crate::Assert::new().action_env(crate::assert::DEFAULT_ACTION_ENV), } } @@ -34,7 +34,7 @@ impl Command { stdin: None, timeout: None, _stderr_to_stdout: false, - config: crate::Assert::new().action_env(crate::DEFAULT_ACTION_ENV), + config: crate::Assert::new().action_env(crate::assert::DEFAULT_ACTION_ENV), } } @@ -456,7 +456,7 @@ impl OutputAssert { pub fn new(output: std::process::Output) -> Self { Self { output, - config: crate::Assert::new().action_env(crate::DEFAULT_ACTION_ENV), + config: crate::Assert::new().action_env(crate::assert::DEFAULT_ACTION_ENV), } } @@ -871,7 +871,7 @@ pub(crate) mod examples { pub fn compile_example<'a>( target_name: &str, args: impl IntoIterator, - ) -> Result { + ) -> Result { crate::debug!("Compiling example {}", target_name); let messages = escargot::CargoBuild::new() .current_target() @@ -879,12 +879,12 @@ pub(crate) mod examples { .example(target_name) .args(args) .exec() - .map_err(|e| crate::Error::new(e.to_string()))?; + .map_err(|e| crate::assert::Error::new(e.to_string()))?; for message in messages { - let message = message.map_err(|e| crate::Error::new(e.to_string()))?; + let message = message.map_err(|e| crate::assert::Error::new(e.to_string()))?; let message = message .decode() - .map_err(|e| crate::Error::new(e.to_string()))?; + .map_err(|e| crate::assert::Error::new(e.to_string()))?; crate::debug!("Message: {:?}", message); if let Some(bin) = decode_example_message(&message) { let (name, bin) = bin?; @@ -893,7 +893,7 @@ pub(crate) mod examples { } } - Err(crate::Error::new(format!( + Err(crate::assert::Error::new(format!( "Unknown error building example {}", target_name ))) @@ -914,8 +914,8 @@ pub(crate) mod examples { pub fn compile_examples<'a>( args: impl IntoIterator, ) -> Result< - impl Iterator)>, - crate::Error, + impl Iterator)>, + crate::assert::Error, > { crate::debug!("Compiling examples"); let mut examples = std::collections::BTreeMap::new(); @@ -926,12 +926,12 @@ pub(crate) mod examples { .examples() .args(args) .exec() - .map_err(|e| crate::Error::new(e.to_string()))?; + .map_err(|e| crate::assert::Error::new(e.to_string()))?; for message in messages { - let message = message.map_err(|e| crate::Error::new(e.to_string()))?; + let message = message.map_err(|e| crate::assert::Error::new(e.to_string()))?; let message = message .decode() - .map_err(|e| crate::Error::new(e.to_string()))?; + .map_err(|e| crate::assert::Error::new(e.to_string()))?; crate::debug!("Message: {:?}", message); if let Some(bin) = decode_example_message(&message) { let (name, bin) = bin?; @@ -945,7 +945,9 @@ pub(crate) mod examples { #[allow(clippy::type_complexity)] fn decode_example_message<'m>( message: &'m escargot::format::Message, - ) -> Option), crate::Error>> { + ) -> Option< + Result<(&'m str, Result), crate::assert::Error>, + > { match message { escargot::format::Message::CompilerMessage(msg) => { let level = msg.message.level; @@ -959,10 +961,10 @@ pub(crate) mod examples { .unwrap_or_else(|| msg.message.message.as_ref()) .to_owned(); if is_example_target(&msg.target) { - let bin = Err(crate::Error::new(output)); + let bin = Err(crate::assert::Error::new(output)); Some(Ok((msg.target.name.as_ref(), bin))) } else { - Some(Err(crate::Error::new(output))) + Some(Err(crate::assert::Error::new(output))) } } else { None diff --git a/crates/snapbox/src/data/mod.rs b/crates/snapbox/src/data/mod.rs index bc67e650..9a1a5dff 100644 --- a/crates/snapbox/src/data/mod.rs +++ b/crates/snapbox/src/data/mod.rs @@ -269,7 +269,7 @@ impl Data { Self::with_inner(DataInner::JsonLines(serde_json::Value::Array(raw.into()))) } - fn error(raw: impl Into, intended: DataFormat) -> Self { + fn error(raw: impl Into, intended: DataFormat) -> Self { Self::with_inner(DataInner::Error(DataError { error: raw.into(), intended, @@ -322,7 +322,7 @@ impl Data { pub fn try_read_from( path: &std::path::Path, data_format: Option, - ) -> Result { + ) -> Result { let data = std::fs::read(path).map_err(|e| format!("Failed to read {}: {}", path.display(), e))?; let data = Self::binary(data); @@ -346,7 +346,7 @@ impl Data { } /// Overwrite a snapshot - pub fn write_to(&self, source: &DataSource) -> Result<(), crate::Error> { + pub fn write_to(&self, source: &DataSource) -> Result<(), crate::assert::Error> { match &source.inner { source::DataSourceInner::Path(p) => self.write_to_path(p), source::DataSourceInner::Inline(p) => runtime::get() @@ -356,7 +356,7 @@ impl Data { } /// Overwrite a snapshot - pub fn write_to_path(&self, path: &std::path::Path) -> Result<(), crate::Error> { + pub fn write_to_path(&self, path: &std::path::Path) -> Result<(), crate::assert::Error> { if let Some(parent) = path.parent() { std::fs::create_dir_all(parent).map_err(|e| { format!("Failed to create parent dir for {}: {}", path.display(), e) @@ -384,7 +384,7 @@ impl Data { } } - pub fn to_bytes(&self) -> Result, crate::Error> { + pub fn to_bytes(&self) -> Result, crate::assert::Error> { match &self.inner { DataInner::Error(err) => Err(err.error.clone()), DataInner::Binary(data) => Ok(data.clone()), @@ -408,7 +408,7 @@ impl Data { } } - fn try_is(self, format: DataFormat) -> Result { + fn try_is(self, format: DataFormat) -> Result { let original = self.format(); let source = self.source; let filters = self.filters; @@ -650,7 +650,7 @@ impl PartialEq for Data { #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct DataError { - error: crate::Error, + error: crate::assert::Error, intended: DataFormat, } diff --git a/crates/snapbox/src/filters/redactions.rs b/crates/snapbox/src/filters/redactions.rs index ad876640..b0d1c461 100644 --- a/crates/snapbox/src/filters/redactions.rs +++ b/crates/snapbox/src/filters/redactions.rs @@ -49,7 +49,7 @@ impl Redactions { &mut self, placeholder: &'static str, value: impl Into, - ) -> Result<(), crate::Error> { + ) -> Result<(), crate::assert::Error> { let placeholder = validate_placeholder(placeholder)?; let value = value.into(); if let Some(inner) = value.inner { @@ -66,14 +66,14 @@ impl Redactions { pub fn extend( &mut self, vars: impl IntoIterator)>, - ) -> Result<(), crate::Error> { + ) -> Result<(), crate::assert::Error> { for (placeholder, value) in vars { self.insert(placeholder, value)?; } Ok(()) } - pub fn remove(&mut self, placeholder: &'static str) -> Result<(), crate::Error> { + pub fn remove(&mut self, placeholder: &'static str) -> Result<(), crate::assert::Error> { let placeholder = validate_placeholder(placeholder)?; self.vars.remove(placeholder); Ok(()) @@ -291,7 +291,7 @@ fn replace_many<'a>( } } -fn validate_placeholder(placeholder: &'static str) -> Result<&'static str, crate::Error> { +fn validate_placeholder(placeholder: &'static str) -> Result<&'static str, crate::assert::Error> { if !placeholder.starts_with('[') || !placeholder.ends_with(']') { return Err(format!("Key `{}` is not enclosed in []", placeholder).into()); } diff --git a/crates/snapbox/src/harness.rs b/crates/snapbox/src/harness.rs index b706ce5f..5bb00671 100644 --- a/crates/snapbox/src/harness.rs +++ b/crates/snapbox/src/harness.rs @@ -35,7 +35,7 @@ //! } //! ``` -use crate::Action; +use crate::assert::Action; use crate::Data; use libtest_mimic::Trial; @@ -81,7 +81,7 @@ where overrides: None, setup, test, - config: crate::Assert::new().action_env(crate::DEFAULT_ACTION_ENV), + config: crate::Assert::new().action_env(crate::assert::DEFAULT_ACTION_ENV), test_output: Default::default(), test_error: Default::default(), } diff --git a/crates/snapbox/src/lib.rs b/crates/snapbox/src/lib.rs index 50626126..563882be 100644 --- a/crates/snapbox/src/lib.rs +++ b/crates/snapbox/src/lib.rs @@ -94,11 +94,9 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] -mod action; -mod assert; -mod error; mod macros; +pub mod assert; pub mod cmd; pub mod data; pub mod filters; @@ -109,20 +107,15 @@ pub mod utils; #[cfg(feature = "harness")] pub mod harness; -pub use action::Action; -pub use action::DEFAULT_ACTION_ENV; pub use assert::Assert; pub use data::Data; pub use data::IntoData; #[cfg(feature = "json")] pub use data::IntoJson; pub use data::ToDebug; -pub use error::Error; pub use filters::Redactions; pub use snapbox_macros::debug; -pub type Result = std::result::Result; - /// Easier access to common traits pub mod prelude { pub use crate::IntoData; @@ -159,7 +152,7 @@ pub mod prelude { #[track_caller] pub fn assert_eq(expected: impl IntoData, actual: impl IntoData) { Assert::new() - .action_env(DEFAULT_ACTION_ENV) + .action_env(assert::DEFAULT_ACTION_ENV) .eq(expected, actual); } @@ -179,7 +172,7 @@ pub fn assert_subset_eq( actual_root: impl Into, ) { Assert::new() - .action_env(DEFAULT_ACTION_ENV) + .action_env(assert::DEFAULT_ACTION_ENV) .subset_eq(expected_root, actual_root); } @@ -206,6 +199,6 @@ pub fn assert_subset_matches( actual_root: impl Into, ) { Assert::new() - .action_env(DEFAULT_ACTION_ENV) + .action_env(assert::DEFAULT_ACTION_ENV) .subset_matches(pattern_root, actual_root); } diff --git a/crates/snapbox/src/path.rs b/crates/snapbox/src/path.rs index d8d4bc02..5869c1e1 100644 --- a/crates/snapbox/src/path.rs +++ b/crates/snapbox/src/path.rs @@ -37,7 +37,7 @@ impl PathFixture { } #[cfg(feature = "path")] - pub fn mutable_temp() -> Result { + pub fn mutable_temp() -> Result { let temp = tempfile::tempdir().map_err(|e| e.to_string())?; // We need to get the `/private` prefix on Mac so variable substitutions work // correctly @@ -47,7 +47,7 @@ impl PathFixture { } #[cfg(feature = "path")] - pub fn mutable_at(target: &std::path::Path) -> Result { + pub fn mutable_at(target: &std::path::Path) -> Result { let _ = std::fs::remove_dir_all(target); std::fs::create_dir_all(target) .map_err(|e| format!("Failed to create {}: {}", target.display(), e))?; @@ -55,7 +55,10 @@ impl PathFixture { } #[cfg(feature = "path")] - pub fn with_template(self, template_root: &std::path::Path) -> Result { + pub fn with_template( + self, + template_root: &std::path::Path, + ) -> Result { match &self.0 { PathFixtureInner::None | PathFixtureInner::Immutable(_) => { return Err("Sandboxing is disabled".into()); @@ -114,7 +117,7 @@ impl Default for PathFixture { #[derive(Clone, Debug, PartialEq, Eq)] pub enum PathDiff { - Failure(crate::Error), + Failure(crate::assert::Error), TypeMismatch { expected_path: std::path::PathBuf, actual_path: std::path::PathBuf, @@ -373,7 +376,7 @@ impl PathDiff { Ok(()) } - pub fn overwrite(&self) -> Result<(), crate::Error> { + pub fn overwrite(&self) -> Result<(), crate::assert::Error> { match self { // Not passing the error up because users most likely want to treat a processing error // differently than an overwrite error @@ -513,7 +516,7 @@ impl Iterator for Walk { pub fn copy_template( source: impl AsRef, dest: impl AsRef, -) -> Result<(), crate::Error> { +) -> Result<(), crate::assert::Error> { let source = source.as_ref(); let dest = dest.as_ref(); let source = canonicalize(source) @@ -535,7 +538,10 @@ pub fn copy_template( } /// Copy a file system entry, without recursing -fn shallow_copy(source: &std::path::Path, dest: &std::path::Path) -> Result<(), crate::Error> { +fn shallow_copy( + source: &std::path::Path, + dest: &std::path::Path, +) -> Result<(), crate::assert::Error> { let meta = source .symlink_metadata() .map_err(|e| format!("Failed to read metadata from {}: {}", source.display(), e))?; diff --git a/crates/trycmd/src/lib.rs b/crates/trycmd/src/lib.rs index a74e572d..565fc1a7 100644 --- a/crates/trycmd/src/lib.rs +++ b/crates/trycmd/src/lib.rs @@ -240,7 +240,7 @@ mod runner; mod spec; pub use cases::TestCases; -pub use snapbox::Error; +pub use snapbox::assert::Error; pub(crate) use registry::BinRegistry; pub(crate) use runner::{Case, Mode, Runner}; diff --git a/crates/trycmd/src/schema.rs b/crates/trycmd/src/schema.rs index 36a0bc69..eb78705a 100644 --- a/crates/trycmd/src/schema.rs +++ b/crates/trycmd/src/schema.rs @@ -446,7 +446,7 @@ fn overwrite_trycmd_status( step: &Step, stdout_line_nums: &mut std::ops::Range, normalized: &mut String, -) -> Result<(), snapbox::Error> { +) -> Result<(), snapbox::assert::Error> { let status = match exit { Some(status) => status, _ => {