| #![cfg(feature = "redactions")] |
| |
| use insta::_macro_support::Selector; |
| #[cfg(feature = "csv")] |
| use insta::assert_csv_snapshot; |
| #[cfg(feature = "json")] |
| use insta::assert_json_snapshot; |
| #[cfg(feature = "ron")] |
| use insta::assert_ron_snapshot; |
| #[cfg(feature = "toml")] |
| use insta::assert_toml_snapshot; |
| #[cfg(feature = "yaml")] |
| use insta::assert_yaml_snapshot; |
| |
| use insta::assert_debug_snapshot; |
| use serde::Serialize; |
| |
| #[test] |
| fn test_selector_parser() { |
| macro_rules! assert_selector_snapshot { |
| ($short:expr, $sel:expr) => { |
| assert_debug_snapshot!($short, Selector::parse($sel).unwrap()); |
| }; |
| } |
| |
| assert_selector_snapshot!("foo_bar", ".foo.bar"); |
| assert_selector_snapshot!("foo_bar_alt", ".foo[\"bar\"]"); |
| assert_selector_snapshot!("foo_bar_full_range", ".foo.bar[]"); |
| assert_selector_snapshot!("foo_bar_range_to", ".foo.bar[:10]"); |
| assert_selector_snapshot!("foo_bar_range_from", ".foo.bar[10:]"); |
| assert_selector_snapshot!("foo_bar_range", ".foo.bar[10:20]"); |
| assert_selector_snapshot!("foo_bar_deep", ".foo.bar.**"); |
| } |
| |
| #[derive(Serialize)] |
| pub struct Email(String); |
| |
| #[derive(Serialize)] |
| pub struct User { |
| id: u32, |
| username: String, |
| email: Email, |
| extra: String, |
| } |
| |
| #[cfg(feature = "yaml")] |
| #[test] |
| fn test_with_random_value() { |
| assert_yaml_snapshot!("user", &User { |
| id: 42, |
| username: "john_doe".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "".to_string(), |
| }, { |
| ".id" => "[id]" |
| }); |
| } |
| |
| #[cfg(feature = "yaml")] |
| #[test] |
| fn test_with_random_value_inline_callback() { |
| assert_yaml_snapshot!("user", &User { |
| id: 23, |
| username: "john_doe".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "".to_string(), |
| }, { |
| ".id" => insta::dynamic_redaction(|value, path| { |
| similar_asserts::assert_eq!(path.to_string(), ".id"); |
| similar_asserts::assert_eq!(value.as_u64().unwrap(), 23); |
| "[id]" |
| }), |
| }); |
| } |
| |
| #[cfg(feature = "yaml")] |
| #[test] |
| fn test_with_random_value_and_trailing_comma() { |
| assert_yaml_snapshot!("user", &User { |
| id: 11, |
| username: "john_doe".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "".to_string(), |
| }, { |
| ".id" => "[id]", |
| }); |
| } |
| |
| #[cfg(feature = "csv")] |
| #[test] |
| fn test_with_random_value_csv() { |
| assert_csv_snapshot!("user_csv", &User { |
| id: 44, |
| username: "julius_csv".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "".to_string(), |
| }, { |
| ".id" => "[id]" |
| }); |
| } |
| |
| #[cfg(feature = "ron")] |
| #[test] |
| fn test_with_random_value_ron() { |
| assert_ron_snapshot!("user_ron", &User { |
| id: 53, |
| username: "john_ron".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "".to_string(), |
| }, { |
| ".id" => "[id]" |
| }); |
| } |
| |
| #[cfg(feature = "toml")] |
| #[test] |
| fn test_with_random_value_toml() { |
| assert_toml_snapshot!("user_toml", &User { |
| id: 53, |
| username: "john_ron".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "".to_string(), |
| }, { |
| ".id" => "[id]" |
| }); |
| } |
| |
| #[cfg(feature = "json")] |
| #[test] |
| fn test_with_random_value_json() { |
| assert_json_snapshot!("user_json", &User { |
| id: 9999, |
| username: "jason_doe".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "ssn goes here".to_string(), |
| }, { |
| ".id" => "[id]", |
| ".extra" => "[extra]" |
| }); |
| } |
| |
| #[cfg(feature = "json")] |
| #[test] |
| fn test_with_random_value_json_settings() { |
| let mut settings = insta::Settings::new(); |
| settings.add_redaction(".id", "[id]"); |
| settings.add_redaction(".extra", "[extra]"); |
| settings.bind(|| { |
| assert_json_snapshot!( |
| "user_json_settings", |
| &User { |
| id: 122, |
| username: "jason_doe".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "ssn goes here".to_string(), |
| } |
| ); |
| }); |
| } |
| |
| #[cfg(feature = "json")] |
| #[test] |
| fn test_with_callbacks() { |
| let mut settings = insta::Settings::new(); |
| settings.add_dynamic_redaction(".id", |value, path| { |
| similar_asserts::assert_eq!(path.to_string(), ".id"); |
| similar_asserts::assert_eq!(value.as_u64().unwrap(), 1234); |
| "[id]" |
| }); |
| settings.bind(|| { |
| assert_json_snapshot!( |
| "user_json_settings_callback", |
| &User { |
| id: 1234, |
| username: "jason_doe".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "extra here".to_string(), |
| } |
| ); |
| }); |
| } |
| |
| #[cfg(feature = "json")] |
| #[test] |
| fn test_with_random_value_json_settings2() { |
| insta::with_settings!({redactions => vec![ |
| (".id", "[id]".into()), |
| (".extra", "[extra]".into()), |
| ]}, { |
| assert_json_snapshot!( |
| &User { |
| id: 975, |
| username: "jason_doe".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "ssn goes here".to_string(), |
| } |
| ); |
| }); |
| } |
| |
| #[cfg(feature = "json")] |
| #[test] |
| fn test_redact_newtype_struct() { |
| #[derive(Serialize)] |
| pub struct UserWrapper(User); |
| |
| let wrapper = UserWrapper(User { |
| id: 42, |
| username: "john_doe".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "".to_string(), |
| }); |
| |
| assert_json_snapshot!(wrapper, { |
| r#".id"# => "[id]" |
| }, @r###" |
| { |
| "id": "[id]", |
| "username": "john_doe", |
| "email": "[email protected]", |
| "extra": "" |
| } |
| "###); |
| } |
| |
| #[cfg(feature = "yaml")] |
| #[test] |
| fn test_redact_newtype_enum() { |
| #[derive(Serialize)] |
| pub enum Role { |
| Admin(User), |
| Visitor { id: String, name: String }, |
| } |
| |
| let visitor = Role::Visitor { |
| id: "my-id".into(), |
| name: "my-name".into(), |
| }; |
| assert_yaml_snapshot!(visitor, { |
| r#".id"# => "[id]", |
| }, @r###" |
| --- |
| Visitor: |
| id: "[id]" |
| name: my-name |
| "###); |
| |
| let admin = Role::Admin(User { |
| id: 42, |
| username: "john_doe".to_string(), |
| email: Email("[email protected]".to_string()), |
| extra: "".to_string(), |
| }); |
| assert_yaml_snapshot!(admin, { |
| r#".id"# => "[id]", |
| }, @r###" |
| --- |
| Admin: |
| id: "[id]" |
| username: john_doe |
| email: john@example.com |
| extra: "" |
| "###); |
| } |
| |
| #[cfg(feature = "json")] |
| #[test] |
| fn test_redact_recursive() { |
| #[derive(Serialize)] |
| pub struct Node { |
| id: u64, |
| next: Option<Box<Node>>, |
| } |
| |
| let root = Node { |
| id: 0, |
| next: Some(Box::new(Node { id: 1, next: None })), |
| }; |
| |
| assert_json_snapshot!(root, { |
| ".**.id" => "[id]", |
| }, @r###" |
| { |
| "id": "[id]", |
| "next": { |
| "id": "[id]", |
| "next": null |
| } |
| } |
| "###); |
| } |
| |
| #[cfg(feature = "yaml")] |
| #[test] |
| fn test_struct_array_redaction() { |
| #[derive(Serialize)] |
| pub struct Product { |
| _id: String, |
| product_name: String, |
| } |
| |
| #[derive(Serialize)] |
| pub struct Checkout { |
| _id: String, |
| products: Vec<Product>, |
| } |
| |
| let checkout = Checkout { |
| _id: "checkout/1".to_string(), |
| products: vec![ |
| Product { |
| _id: "product/1".to_string(), |
| product_name: "a car".to_string(), |
| }, |
| Product { |
| _id: "product/2".to_string(), |
| product_name: "a boat".to_string(), |
| }, |
| ], |
| }; |
| |
| assert_yaml_snapshot!(vec![checkout], { |
| "[]._id" => "[checkout_id]", |
| "[].products[]._id" => "[product_id]", |
| "[].products[].product_name" => "[product_name]", |
| }); |
| } |
| |
| #[cfg(feature = "yaml")] |
| #[test] |
| fn test_map_key_redaction() { |
| #[derive(Serialize, Hash, PartialEq, PartialOrd, Eq, Ord)] |
| struct Key { |
| bucket: u32, |
| value: u32, |
| } |
| |
| #[derive(Serialize)] |
| struct Foo { |
| hm: std::collections::HashMap<Key, u32>, |
| btm: std::collections::BTreeMap<(u32, u32), u32>, |
| } |
| |
| let mut hm = std::collections::HashMap::new(); |
| hm.insert( |
| Key { |
| bucket: 1, |
| value: 0, |
| }, |
| 42, |
| ); |
| let mut btm = std::collections::BTreeMap::new(); |
| btm.insert((0, 0), 23); |
| let foo_value = Foo { hm, btm }; |
| |
| assert_yaml_snapshot!(foo_value, { |
| ".hm.$key.bucket" => "[bucket]", |
| ".btm.$key" => "[key]", |
| }); |
| } |
| |
| #[cfg(feature = "json")] |
| #[test] |
| fn test_ordering() { |
| #[derive(Debug, Serialize)] |
| pub struct User { |
| id: u64, |
| username: String, |
| flags: std::collections::HashSet<String>, |
| } |
| |
| let mut settings = insta::Settings::new(); |
| settings.add_redaction(".id", "[id]"); |
| settings.sort_selector(".flags"); |
| settings.bind(|| { |
| assert_json_snapshot!( |
| "user_json_flags", |
| &User { |
| id: 122, |
| username: "jason_doe".to_string(), |
| flags: vec!["zzz".into(), "foo".into(), "aha".into(), "is_admin".into()] |
| .into_iter() |
| .collect(), |
| } |
| ); |
| }); |
| } |
| |
| #[cfg(feature = "json")] |
| #[test] |
| fn test_ordering_newtype_set() { |
| #[derive(Debug, Serialize)] |
| pub struct MySet(std::collections::HashSet<String>); |
| |
| #[derive(Debug, Serialize)] |
| pub struct User { |
| id: u64, |
| username: String, |
| flags: MySet, |
| } |
| |
| assert_json_snapshot!( |
| "user_json_flags_alt", |
| &User { |
| id: 122, |
| username: "jason_doe".to_string(), |
| flags: MySet(vec!["zzz".into(), "foo".into(), "aha".into(), "is_admin".into()] |
| .into_iter() |
| .collect()), |
| }, |
| { |
| "." => insta::sorted_redaction(), |
| ".flags" => insta::sorted_redaction() |
| } |
| ); |
| } |
| |
| #[cfg(feature = "json")] |
| #[test] |
| fn test_rounded_redaction() { |
| #[derive(Debug, Serialize)] |
| pub struct MyPoint { |
| x: f64, |
| y: f64, |
| } |
| |
| assert_json_snapshot!( |
| "rounded_redaction", |
| &MyPoint { |
| x: 1.0 / 3.0, |
| y: 6.0 / 3.0, |
| }, |
| { |
| ".x" => insta::rounded_redaction(4), |
| ".y" => insta::rounded_redaction(4), |
| } |
| ); |
| } |