// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Testing utilities for a `DiagnosticsHierarchy`.
//!
//! Pretty much the useful [`assert_data_tree`][assert_data_tree] macro plus some utilities for it.

use {
    crate::{
        ArrayContent, ArrayFormat, Bucket, DiagnosticsHierarchy, ExponentialHistogramParams,
        LinearHistogramParams, Property, EXPONENTIAL_HISTOGRAM_EXTRA_SLOTS,
        LINEAR_HISTOGRAM_EXTRA_SLOTS,
    },
    anyhow::{bail, format_err, Error},
    difference::{Changeset, Difference},
    num_traits::One,
    std::{
        borrow::Cow,
        collections::BTreeSet,
        fmt::{Debug, Display, Formatter, Result as FmtResult},
        ops::{Add, AddAssign, MulAssign},
    },
};

/// Macro to simplify creating `TreeAssertion`s. Commonly used indirectly through the second
/// parameter of `assert_data_tree!`. See `assert_data_tree!` for more usage examples.
///
/// Each leaf value must be a type that implements either `PropertyAssertion` or `TreeAssertion`.
///
/// Example:
/// ```
/// // Manual creation of `TreeAssertion`.
/// let mut root = TreeAssertion::new("root", true);
/// root.add_property_assertion("a-string-property", Box::new("expected-string-value"));
/// let mut child = TreeAssertion::new("child", true);
/// child.add_property_assertion("any-property", Box::new(AnyProperty));
/// root.add_child_assertion(child);
/// root.add_child_assertion(opaque_child);
///
/// // Creation with `tree_assertion!`.
/// let root = tree_assertion!(
///     root: {
///         "a-string-property": "expected-string-value",
///         child: {
///             "any-property": AnyProperty,
///         },
///         opaque_child, // required trailing comma for `TreeAssertion` expressions
///     }
/// );
/// ```
///
/// Note that `TreeAssertion`s given directly to the macro must always be followed by `,`.
#[macro_export]
macro_rules! tree_assertion {
    (@build $tree_assertion:expr,) => {};

    // Exact match of tree
    (@build $tree_assertion:expr, var $key:ident: { $($sub:tt)* }) => {{
        #[allow(unused_mut)]
        let mut child_tree_assertion = TreeAssertion::new($key, true);
        $crate::tree_assertion!(@build child_tree_assertion, $($sub)*);
        $tree_assertion.add_child_assertion(child_tree_assertion);
    }};
    (@build $tree_assertion:expr, var $key:ident: { $($sub:tt)* }, $($rest:tt)*) => {{
        $crate::tree_assertion!(@build $tree_assertion, var $key: { $($sub)* });
        $crate::tree_assertion!(@build $tree_assertion, $($rest)*);
    }};

    // Partial match of tree
    (@build $tree_assertion:expr, var $key:ident: contains { $($sub:tt)* }) => {{
        #[allow(unused_mut)]
        let mut child_tree_assertion = TreeAssertion::new($key, false);
        $crate::tree_assertion!(@build child_tree_assertion, $($sub)*);
        $tree_assertion.add_child_assertion(child_tree_assertion);
    }};
    (@build $tree_assertion:expr, var $key:ident: contains { $($sub:tt)* }, $($rest:tt)*) => {{
        $crate::tree_assertion!(@build $tree_assertion, var $key: contains { $($sub)* });
        $crate::tree_assertion!(@build $tree_assertion, $($rest)*);
    }};

    // Matching properties of a tree
    (@build $tree_assertion:expr, var $key:ident: $assertion:expr) => {{
        $tree_assertion.add_property_assertion($key, Box::new($assertion))
    }};
    (@build $tree_assertion:expr, var $key:ident: $assertion:expr, $($rest:tt)*) => {{
        $crate::tree_assertion!(@build $tree_assertion, var $key: $assertion);
        $crate::tree_assertion!(@build $tree_assertion, $($rest)*);
    }};

    // Key identifier format
    (@build $tree_assertion:expr, $key:ident: $($rest:tt)+) => {{
        let key = stringify!($key);
        $crate::tree_assertion!(@build $tree_assertion, var key: $($rest)+);
    }};
    // Allows string literal for key
    (@build $tree_assertion:expr, $key:tt: $($rest:tt)+) => {{
        let key: &'static str = $key;
        $crate::tree_assertion!(@build $tree_assertion, var key: $($rest)+);
    }};
    // Allows an expression that resolves into a String for key
    (@build $tree_assertion:expr, $key:expr => $($rest:tt)+) => {{
        let key_string : String = $key;
        let key = &key_string;
        $crate::tree_assertion!(@build $tree_assertion, var key: $($rest)+);
    }};
    // Allows an expression that resolves into a TreeAssertion
    (@build $tree_assertion:expr, $child_assertion:expr, $($rest:tt)*) => {{
        $tree_assertion.add_child_assertion($child_assertion);
        $crate::tree_assertion!(@build $tree_assertion, $($rest)*);
    }};

    // Entry points
    (var $key:ident: { $($sub:tt)* }) => {{
        use $crate::testing::TreeAssertion;
        #[allow(unused_mut)]
        let mut tree_assertion = TreeAssertion::new($key, true);
        $crate::tree_assertion!(@build tree_assertion, $($sub)*);
        tree_assertion
    }};
    (var $key:ident: contains { $($sub:tt)* }) => {{
        use $crate::testing::TreeAssertion;
        #[allow(unused_mut)]
        let mut tree_assertion = TreeAssertion::new($key, false);
        $crate::tree_assertion!(@build tree_assertion, $($sub)*);
        tree_assertion
    }};
    ($key:ident: $($rest:tt)+) => {{
        let key = stringify!($key);
        $crate::tree_assertion!(var key: $($rest)+)
    }};
    ($key:tt: $($rest:tt)+) => {{
        let key: &'static str = $key;
        $crate::tree_assertion!(var key: $($rest)+)
    }};
}

/// Macro to simplify tree matching in tests. The first argument is the actual tree passed as a
/// `DiagnosticsHierarchyGetter` (e.g. a `DiagnosticsHierarchy` or an `Inspector`). The second argument is given
/// to `tree_assertion!` which creates a `TreeAssertion` to validate the tree.
///
/// Each leaf value must be a type that implements either `PropertyAssertion` or `TreeAssertion`.
///
/// Example:
/// ```
/// // Actual tree
/// let diagnostics_hierarchy = DiagnosticsHierarchy {
///     name: "key".to_string(),
///     properties: vec![
///         Property::String("sub".to_string(), "sub_value".to_string()),
///         Property::String("sub2".to_string(), "sub2_value".to_string()),
///     ],
///     children: vec![
///        DiagnosticsHierarchy {
///            name: "child1".to_string(),
///            properties: vec![
///                Property::Int("child1_sub".to_string(), 10i64),
///            ],
///            children: vec![],
///        },
///        DiagnosticsHierarchy {
///            name: "child2".to_string(),
///            properties: vec![
///                Property::Uint("child2_sub".to_string(), 20u64),
///            ],
///            children: vec![],
///        },
///    ],
/// };
///
/// assert_data_tree!(
///     diagnostics_hierarchy,
///     key: {
///         sub: AnyProperty,   // only verify that `sub` is a property of `key`
///         sub2: "sub2_value",
///         child1: {
///             child1_sub: 10i64,
///         },
///         child2: {
///             child2_sub: 20u64,
///         },
///     }
/// );
/// ```
///
/// In order to do a partial match on a tree, use the `contains` keyword:
/// ```
/// assert_data_tree!(diagnostics_hierarchy, key: contains {
///     sub: "sub_value",
///     child1: contains {},
/// });
/// ```
///
/// In order to do a match on a tree where the keys need to be computed (they are some
/// expression), you'll need to use `=>` instead of `:`:
///
/// ```
/// assert_data_tree!(diagnostics_hierarchy, key: {
///     key_fn() => "value",
/// })
/// ```
/// Note that `key_fn` has to return a `String`.
///
/// The first argument can be an `Inspector`, in which case the whole tree is read from the
/// `Inspector` and matched against:
/// ```
/// let inspector = Inspector::new().unwrap();
/// assert_data_tree!(inspector, root: {});
/// ```
///
/// `TreeAssertion`s made elsewhere can be included bodily in the macro, but must always be followed
/// by a trailing comma:
/// assert_data_tree!(
///     diagnostics_hierarchy,
///     key: {
///         make_child_tree_assertion(), // required trailing comma
///     }
/// );
///
/// A tree may contain multiple properties or children with the same name. This macro does *not*
/// support matching against them, and will throw an error if it detects duplicates. This is
/// to provide warning for users who accidentally log the same name multiple times, as the
/// behavior for reading properties or children with duplicate names is not well defined.
#[macro_export]
macro_rules! assert_data_tree {
    ($diagnostics_hierarchy:expr, $($rest:tt)+) => {{
        let tree_assertion = $crate::tree_assertion!($($rest)+);

        use $crate::testing::DiagnosticsHierarchyGetter as _;
        if let Err(e) = tree_assertion.run($diagnostics_hierarchy.get_diagnostics_hierarchy().as_ref()) {
            panic!("tree assertion fails: {}", e);
        }
    }};
}

/// A type which can function as a "view" into a diagnostics hierarchy, optionally allocating a new
/// instance to service a request.
pub trait DiagnosticsHierarchyGetter<K: Clone> {
    fn get_diagnostics_hierarchy(&self) -> Cow<'_, DiagnosticsHierarchy<K>>;
}

impl<K: Clone> DiagnosticsHierarchyGetter<K> for DiagnosticsHierarchy<K> {
    fn get_diagnostics_hierarchy(&self) -> Cow<'_, DiagnosticsHierarchy<K>> {
        Cow::Borrowed(self)
    }
}

/// A difference between expected and actual output.
struct Diff(Changeset);

impl Diff {
    fn new(expected: &dyn Debug, actual: &dyn Debug) -> Self {
        let expected = format!("{:#?}", expected);
        let actual = format!("{:#?}", actual);
        Diff(Changeset::new(&expected, &actual, "\n"))
    }
}

impl Display for Diff {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        writeln!(f, "(-) Expected vs. (+) Actual:")?;
        for diff in &self.0.diffs {
            let (prefix, contents) = match diff {
                Difference::Same(same) => ("  ", same),
                Difference::Add(added) => ("+ ", added),
                Difference::Rem(removed) => ("- ", removed),
            };
            for line in contents.split("\n") {
                writeln!(f, "{}{}", prefix, line)?;
            }
        }
        Ok(())
    }
}

macro_rules! eq_or_bail {
    ($expected:expr, $actual:expr) => {{
        if $expected != $actual {
            let changes = Diff::new(&$expected, &$actual);
            return Err(format_err!("\n {}", changes));
        }
    }};
    ($expected:expr, $actual:expr, $($args:tt)+) => {{
        if $expected != $actual {
            let changes = Diff::new(&$expected, &$actual);
            return Err(format_err!("{}:\n {}", format!($($args)+), changes));
        }
    }}
}

/// Struct for matching against a Data tree (DiagnosticsHierarchy).
pub struct TreeAssertion<K = String> {
    /// Expected name of the node being compared against
    name: String,
    /// Friendly name that includes path from ancestors. Mainly used to indicate which node fails
    /// in error message
    path: String,
    /// Expected property names and assertions to match the actual properties against
    properties: Vec<(String, Box<dyn PropertyAssertion<K>>)>,
    /// Assertions to match against child trees
    children: Vec<TreeAssertion<K>>,
    /// Whether all properties and children of the tree should be checked
    exact_match: bool,
}

impl<K> TreeAssertion<K>
where
    K: AsRef<str>,
{
    /// Create a new `TreeAssertion`. The |name| argument is the expected name of the tree to be
    /// compared against. Set |exact_match| to true to specify that all properties and children of
    /// the tree should be checked. To perform partial matching of the tree, set it to false.
    pub fn new(name: &str, exact_match: bool) -> Self {
        Self {
            name: name.to_string(),
            path: name.to_string(),
            properties: vec![],
            children: vec![],
            exact_match,
        }
    }

    /// Adds a property assertion to this tree assertion.
    pub fn add_property_assertion(&mut self, key: &str, assertion: Box<dyn PropertyAssertion<K>>) {
        self.properties.push((key.to_owned(), assertion));
    }

    /// Adds a tree assertion as a child of this tree assertion.
    pub fn add_child_assertion(&mut self, mut assertion: TreeAssertion<K>) {
        assertion.path = format!("{}.{}", self.path, assertion.name);
        self.children.push(assertion);
    }

    /// Check whether |actual| tree satisfies criteria defined by `TreeAssertion`. Return `Ok` if
    /// assertion passes and `Error` if assertion fails.
    pub fn run(&self, actual: &DiagnosticsHierarchy<K>) -> Result<(), Error> {
        eq_or_bail!(self.name, actual.name, "node `{}` - expected node name != actual", self.path);

        if self.exact_match {
            let properties_names = self.properties.iter().map(|p| p.0.to_string());
            let children_names = self.children.iter().map(|c| c.name.to_string());
            let keys: BTreeSet<String> = properties_names.chain(children_names).collect();

            let actual_props = actual.properties.iter().map(|p| p.name().to_string());
            let actual_children = actual.children.iter().map(|c| c.name.to_string());
            let actual_keys: BTreeSet<String> = actual_props.chain(actual_children).collect();
            eq_or_bail!(keys, actual_keys, "node `{}` - expected keys != actual", self.path);
        }

        for (name, assertion) in self.properties.iter() {
            let mut matched = actual.properties.iter().filter(|p| p.key().as_ref() == name);
            let first_match = matched.next();
            if let Some(_second_match) = matched.next() {
                bail!("node `{}` - multiple properties found with name `{}`", self.path, name);
            }
            match first_match {
                Some(property) => {
                    if let Err(e) = assertion.run(property) {
                        bail!(
                            "node `{}` - assertion fails for property `{}`. Reason: {}",
                            self.path,
                            name,
                            e
                        );
                    }
                }
                None => bail!("node `{}` - no property named `{}`", self.path, name),
            }
        }
        for assertion in self.children.iter() {
            let mut matched = actual.children.iter().filter(|c| c.name == assertion.name);
            let first_match = matched.next();
            if let Some(_second_match) = matched.next() {
                bail!(
                    "node `{}` - multiple children found with name `{}`",
                    self.path,
                    assertion.name
                );
            }
            match first_match {
                Some(child) => assertion.run(&child)?,
                None => bail!("node `{}` - no child named `{}`", self.path, assertion.name),
            }
        }
        Ok(())
    }
}

/// Trait implemented by types that can act as properies for assertion.
pub trait PropertyAssertion<K = String> {
    /// Check whether |actual| property satisfies criteria. Return `Ok` if assertion passes and
    /// `Error` if assertion fails.
    fn run(&self, actual: &Property<K>) -> Result<(), Error>;
}

macro_rules! impl_property_assertion {
    ($prop_variant:ident, $($ty:ty),+) => {
        $(
            impl<K> PropertyAssertion<K> for $ty {
                fn run(&self, actual: &Property<K>) -> Result<(), Error> {
                    if let Property::$prop_variant(_key, value, ..) = actual {
                        eq_or_bail!(self, value);
                    } else {
                        return Err(format_err!("expected {}, found {}",
                            stringify!($prop_variant), actual.discriminant_name()));
                    }
                    Ok(())
                }
            }
        )+
    }
}

macro_rules! impl_array_properties_assertion {
    ($prop_variant:ident, $($ty:ty),+) => {
        $(
            /// Asserts primitive arrays
            impl<K> PropertyAssertion<K> for Vec<$ty> {
                fn run(&self, actual: &Property<K>) -> Result<(), Error> {
                    if let Property::$prop_variant(_key, value, ..) = actual {
                        match &value {
                            ArrayContent::Values(values) => eq_or_bail!(self, values),
                            _ => {
                                return Err(format_err!(
                                    "expected a {} array, got a histogram",
                                    stringify!($prop_variant)
                                ));
                            }
                        }
                    } else {
                        return Err(format_err!("expected {}, found {}",
                            stringify!($prop_variant), actual.discriminant_name()));
                    }
                    Ok(())
                }
            }

            /// Asserts an array of buckets
            impl<K> PropertyAssertion<K> for Vec<Bucket<$ty>> {
                fn run(&self, actual: &Property<K>) -> Result<(), Error> {
                    if let Property::$prop_variant(_key, value, ..) = actual {
                        match &value {
                            ArrayContent::Buckets(buckets) => eq_or_bail!(self, buckets),
                            _ => {
                                return Err(format_err!(
                                    "expected a {} array, got a histogram",
                                    stringify!($prop_variant)
                                ));
                            }
                        }
                    } else {
                        return Err(format_err!("expected {}, found {}",
                            stringify!($prop_variant), actual.discriminant_name()));
                    }
                    Ok(())
                }
            }

            /// Asserts a histogram.
            impl<K> PropertyAssertion<K> for HistogramAssertion<$ty> {
                fn run(&self, actual: &Property<K>) -> Result<(), Error> {
                    if let Property::$prop_variant(_key, value, ..) = actual {
                        let expected_content =
                            ArrayContent::new(self.values.clone(), self.format.clone()).map_err(
                                |e| {
                                    format_err!(
                                        "failed to load array content for expected assertion {}: {:?}",
                                        stringify!($prop_variant),
                                        e
                                    )
                                },
                            )?;
                        eq_or_bail!(&expected_content, value);
                    } else {
                        return Err(format_err!(
                            "expected {}, found {}",
                            stringify!($prop_variant),
                            actual.discriminant_name(),
                        ));
                    }
                    Ok(())
                }
            }
        )+
    }
}

impl_property_assertion!(String, &str, String);
impl_property_assertion!(Bytes, Vec<u8>);
impl_property_assertion!(Uint, u64);
impl_property_assertion!(Int, i64);
impl_property_assertion!(Double, f64);
impl_property_assertion!(Bool, bool);
impl_array_properties_assertion!(DoubleArray, f64);
impl_array_properties_assertion!(IntArray, i64);
impl_array_properties_assertion!(UintArray, u64);

/// A PropertyAssertion that always passes
pub struct AnyProperty;

impl<K> PropertyAssertion<K> for AnyProperty {
    fn run(&self, _actual: &Property<K>) -> Result<(), Error> {
        Ok(())
    }
}

/// A PropertyAssertion that passes for non-zero, unsigned integers.
///
/// TODO(fxbug.dev/62447): generalize this to use the >= operator.
pub struct NonZeroUintProperty;

impl<K> PropertyAssertion<K> for NonZeroUintProperty {
    fn run(&self, actual: &Property<K>) -> Result<(), Error> {
        match actual {
            Property::Uint(_, v) if *v != 0 => Ok(()),
            Property::Uint(_, v) if *v == 0 => {
                Err(format_err!("expected non-zero integer, found 0"))
            }
            _ => {
                Err(format_err!("expected non-zero integer, found {}", actual.discriminant_name()))
            }
        }
    }
}

/// An assertion for a histogram property.
pub struct HistogramAssertion<T> {
    format: ArrayFormat,
    values: Vec<T>,
}

impl<T: MulAssign + AddAssign + PartialOrd + Add<Output = T> + Copy + Default + One>
    HistogramAssertion<T>
{
    /// Creates a new histogram assertion for a linear histogram with the given parameters.
    pub fn linear(params: LinearHistogramParams<T>) -> Self {
        let mut values = vec![T::default(); params.buckets + LINEAR_HISTOGRAM_EXTRA_SLOTS];
        values[0] = params.floor;
        values[1] = params.step_size;
        Self { format: ArrayFormat::LinearHistogram, values }
    }

    /// Creates a new histogram assertion for an exponential histogram with the given parameters.
    pub fn exponential(params: ExponentialHistogramParams<T>) -> Self {
        let mut values = vec![T::default(); params.buckets + EXPONENTIAL_HISTOGRAM_EXTRA_SLOTS];
        values[0] = params.floor;
        values[1] = params.initial_step;
        values[2] = params.step_multiplier;
        Self { format: ArrayFormat::ExponentialHistogram, values }
    }

    /// Inserts the list of values to the histogram for asserting them.
    pub fn insert_values(&mut self, values: Vec<T>) {
        match self.format {
            ArrayFormat::ExponentialHistogram => {
                for value in values {
                    self.insert_exp(value);
                }
            }
            ArrayFormat::LinearHistogram => {
                for value in values {
                    self.insert_linear(value);
                }
            }
            ArrayFormat::Default => {
                unreachable!("can't construct a histogram assertion for arrays");
            }
        }
    }

    fn insert_linear(&mut self, value: T) {
        let value_index = {
            let mut current_floor = self.values[0];
            let step_size = self.values[1];
            // Start in the underflow index.
            let mut index = LINEAR_HISTOGRAM_EXTRA_SLOTS - 2;
            while value >= current_floor && index < self.values.len() - 1 {
                current_floor += step_size;
                index += 1;
            }
            index as usize
        };
        self.values[value_index] += T::one();
    }

    fn insert_exp(&mut self, value: T) {
        let value_index = {
            let floor = self.values[0];
            let mut current_floor = self.values[0];
            let mut offset = self.values[1];
            let step_multiplier = self.values[2];
            // Start in the underflow index.
            let mut index = EXPONENTIAL_HISTOGRAM_EXTRA_SLOTS - 2;
            while value >= current_floor && index < self.values.len() - 1 {
                current_floor = floor + offset;
                offset *= step_multiplier;
                index += 1;
            }
            index as usize
        };
        self.values[value_index] += T::one();
    }
}

#[cfg(test)]
mod tests {
    use {super::*, crate::Bucket};

    #[test]
    fn test_exact_match_simple() {
        let diagnostics_hierarchy = simple_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub: "sub_value",
            sub2: "sub2_value",
        });
    }

    #[test]
    fn test_exact_match_complex() {
        let diagnostics_hierarchy = complex_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub: "sub_value",
            sub2: "sub2_value",
            child1: {
                child1_sub: 10i64,
            },
            child2: {
                child2_sub: 20u64,
            },
        });
    }

    #[test]
    #[should_panic]
    fn test_exact_match_mismatched_property_name() {
        let diagnostics_hierarchy = simple_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub: "sub_value",
            sub3: "sub2_value",
        });
    }

    #[test]
    #[should_panic]
    fn test_exact_match_mismatched_child_name() {
        let diagnostics_hierarchy = complex_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub: "sub_value",
            sub2: "sub2_value",
            child1: {
                child1_sub: 10i64,
            },
            child3: {
                child2_sub: 20u64,
            },
        });
    }

    #[test]
    #[should_panic]
    fn test_exact_match_mismatched_property_name_in_child() {
        let diagnostics_hierarchy = complex_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub: "sub_value",
            sub2: "sub2_value",
            child1: {
                child2_sub: 10i64,
            },
            child2: {
                child2_sub: 20u64,
            },
        });
    }

    #[test]
    #[should_panic]
    fn test_exact_match_mismatched_property_value() {
        let diagnostics_hierarchy = simple_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub: "sub2_value",
            sub2: "sub2_value",
        });
    }

    #[test]
    #[should_panic]
    fn test_exact_match_missing_property() {
        let diagnostics_hierarchy = simple_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub: "sub_value",
        });
    }

    #[test]
    #[should_panic]
    fn test_exact_match_missing_child() {
        let diagnostics_hierarchy = complex_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub: "sub_value",
            sub2: "sub2_value",
            child1: {
                child1_sub: 10i64,
            },
        });
    }

    #[test]
    fn test_partial_match_success() {
        let diagnostics_hierarchy = complex_tree();

        // only verify the top tree name
        assert_data_tree!(diagnostics_hierarchy, key: contains {});

        // verify parts of the tree
        assert_data_tree!(diagnostics_hierarchy, key: contains {
            sub: "sub_value",
            child1: contains {},
        });
    }

    #[test]
    #[should_panic]
    fn test_partial_match_nonexistent_property() {
        let diagnostics_hierarchy = simple_tree();
        assert_data_tree!(diagnostics_hierarchy, key: contains {
            sub3: AnyProperty,
        });
    }

    #[test]
    fn test_ignore_property_value() {
        let diagnostics_hierarchy = simple_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub: AnyProperty,
            sub2: "sub2_value",
        });
    }

    #[test]
    #[should_panic]
    fn test_ignore_property_value_property_name_is_still_checked() {
        let diagnostics_hierarchy = simple_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub1: AnyProperty,
            sub2: "sub2_value",
        })
    }

    #[test]
    fn test_expr_key_syntax() {
        let diagnostics_hierarchy = DiagnosticsHierarchy::new(
            "key",
            vec![Property::String("@time".to_string(), "1.000".to_string())],
            vec![],
        );
        assert_data_tree!(diagnostics_hierarchy, key: {
            "@time": "1.000"
        });
    }

    #[test]
    fn test_var_key_syntax() {
        let diagnostics_hierarchy = DiagnosticsHierarchy::new(
            "key",
            vec![Property::String("@time".to_string(), "1.000".to_string())],
            vec![],
        );
        let time_key = "@time";
        assert_data_tree!(diagnostics_hierarchy, key: {
            var time_key: "1.000"
        });
    }

    #[test]
    fn test_arrays() {
        let diagnostics_hierarchy = DiagnosticsHierarchy::new(
            "key",
            vec![
                Property::UintArray("@uints".to_string(), ArrayContent::Values(vec![1, 2, 3])),
                Property::IntArray("@ints".to_string(), ArrayContent::Values(vec![-2, -4, 0])),
                Property::DoubleArray(
                    "@doubles".to_string(),
                    ArrayContent::Values(vec![1.3, 2.5, -3.6]),
                ),
            ],
            vec![],
        );
        assert_data_tree!(diagnostics_hierarchy, key: {
            "@uints": vec![1u64, 2, 3],
            "@ints": vec![-2i64, -4, 0],
            "@doubles": vec![1.3, 2.5, -3.6]
        });
    }

    #[test]
    fn test_histograms() {
        let diagnostics_hierarchy = DiagnosticsHierarchy::new(
            "key",
            vec![
                Property::UintArray(
                    "@linear-uints".to_string(),
                    ArrayContent::new(vec![1, 2, 3, 4, 5], ArrayFormat::LinearHistogram).unwrap(),
                ),
                Property::IntArray(
                    "@linear-ints".to_string(),
                    ArrayContent::new(vec![6, 7, 8, 9, 10], ArrayFormat::LinearHistogram).unwrap(),
                ),
                Property::DoubleArray(
                    "@linear-doubles".to_string(),
                    ArrayContent::new(vec![1.0, 2.0, 4.0, 5.0, 6.0], ArrayFormat::LinearHistogram)
                        .unwrap(),
                ),
                Property::UintArray(
                    "@exp-uints".to_string(),
                    ArrayContent::new(vec![2, 4, 6, 8, 10, 12], ArrayFormat::ExponentialHistogram)
                        .unwrap(),
                ),
                Property::IntArray(
                    "@exp-ints".to_string(),
                    ArrayContent::new(vec![1, 3, 5, 7, 9, 11], ArrayFormat::ExponentialHistogram)
                        .unwrap(),
                ),
                Property::DoubleArray(
                    "@exp-doubles".to_string(),
                    ArrayContent::new(
                        vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0],
                        ArrayFormat::ExponentialHistogram,
                    )
                    .unwrap(),
                ),
            ],
            vec![],
        );
        let mut linear_assertion = HistogramAssertion::linear(LinearHistogramParams {
            floor: 1u64,
            step_size: 2,
            buckets: 1,
        });
        linear_assertion.insert_values(vec![0, 0, 0, 2, 2, 2, 2, 4, 4, 4, 4, 4]);
        let mut exponential_assertion =
            HistogramAssertion::exponential(ExponentialHistogramParams {
                floor: 1.0,
                initial_step: 2.0,
                step_multiplier: 3.0,
                buckets: 1,
            });
        exponential_assertion.insert_values(vec![
            -3.1, -2.2, -1.3, 0.0, 1.1, 1.2, 2.5, 2.8, 2.0, 3.1, 4.2, 5.3, 6.4, 7.5, 8.6,
        ]);
        assert_data_tree!(diagnostics_hierarchy, key: {
            "@linear-uints": linear_assertion,
            "@linear-ints": vec![
                Bucket { floor: i64::MIN, ceiling: 6, count: 8 },
                Bucket { floor: 6, ceiling: 13, count: 9 },
                Bucket { floor: 13, ceiling: i64::MAX, count: 10 }
            ],
            "@linear-doubles": vec![
                Bucket { floor: f64::MIN, ceiling: 1.0, count: 4.0 },
                Bucket { floor: 1.0, ceiling: 3.0, count: 5.0 },
                Bucket { floor: 3.0, ceiling: f64::MAX, count: 6.0 }
            ],
            "@exp-uints": vec![
                Bucket { floor: 0, ceiling: 2, count: 8 },
                Bucket { floor: 2, ceiling: 6, count: 10 },
                Bucket { floor: 6, ceiling: u64::MAX, count: 12 }
            ],
            "@exp-ints": vec![
                Bucket { floor: i64::MIN, ceiling: 1, count: 7 },
                Bucket { floor: 1, ceiling: 4, count: 9 },
                Bucket { floor: 4, ceiling: i64::MAX, count: 11 }
            ],
            "@exp-doubles": exponential_assertion,
        });
    }

    #[test]
    fn test_matching_tree_assertion_expression() {
        let diagnostics_hierarchy = complex_tree();
        let child1 = tree_assertion!(
            child1: {
                child1_sub: 10i64,
            }
        );
        assert_data_tree!(diagnostics_hierarchy, key: {
            sub: "sub_value",
            sub2: "sub2_value",
            child1,
            tree_assertion!(
                child2: {
                    child2_sub: 20u64,
                }
            ),
        });
    }

    #[test]
    #[should_panic]
    fn test_matching_non_unique_property_fails() {
        let diagnostics_hierarchy = non_unique_prop_tree();
        assert_data_tree!(diagnostics_hierarchy, key: { prop: "prop_value#0" });
    }

    #[test]
    #[should_panic]
    fn test_matching_non_unique_property_fails_2() {
        let diagnostics_hierarchy = non_unique_prop_tree();
        assert_data_tree!(diagnostics_hierarchy, key: { prop: "prop_value#1" });
    }

    #[test]
    #[should_panic]
    fn test_matching_non_unique_property_fails_3() {
        let diagnostics_hierarchy = non_unique_prop_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            prop: "prop_value#0",
            prop: "prop_value#1",
        });
    }

    #[test]
    #[should_panic]
    fn test_matching_non_unique_child_fails() {
        let diagnostics_hierarchy = non_unique_child_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            child: {
                prop: 10i64
            }
        });
    }

    #[test]
    #[should_panic]
    fn test_matching_non_unique_child_fails_2() {
        let diagnostics_hierarchy = non_unique_child_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            child: {
                prop: 20i64
            }
        });
    }

    #[test]
    #[should_panic]
    fn test_matching_non_unique_child_fails_3() {
        let diagnostics_hierarchy = non_unique_child_tree();
        assert_data_tree!(diagnostics_hierarchy, key: {
            child: {
                prop: 10i64,
            },
            child: {
                prop: 20i64,
            },
        });
    }

    #[test]
    fn test_nonzero_uint_property_passes() {
        let diagnostics_hierarchy = DiagnosticsHierarchy::new(
            "key",
            vec![
                Property::Uint("value1".to_string(), 10u64),
                Property::Uint("value2".to_string(), 20u64),
            ],
            vec![],
        );
        assert_data_tree!(diagnostics_hierarchy, key: {
            value1: NonZeroUintProperty,
            value2: NonZeroUintProperty,
        });
    }

    #[test]
    #[should_panic]
    fn test_nonzero_uint_property_fails() {
        let diagnostics_hierarchy = DiagnosticsHierarchy::new(
            "key",
            vec![
                Property::Int("value1".to_string(), 10i64),
                Property::Uint("value2".to_string(), 0u64),
                Property::String("value3".to_string(), "string_value".to_string()),
            ],
            vec![],
        );
        assert_data_tree!(diagnostics_hierarchy, key: {
            value1: NonZeroUintProperty,
            value2: NonZeroUintProperty,
            value3: NonZeroUintProperty,
        });
    }

    fn simple_tree() -> DiagnosticsHierarchy {
        DiagnosticsHierarchy::new(
            "key",
            vec![
                Property::String("sub".to_string(), "sub_value".to_string()),
                Property::String("sub2".to_string(), "sub2_value".to_string()),
            ],
            vec![],
        )
    }

    fn complex_tree() -> DiagnosticsHierarchy {
        DiagnosticsHierarchy::new(
            "key",
            vec![
                Property::String("sub".to_string(), "sub_value".to_string()),
                Property::String("sub2".to_string(), "sub2_value".to_string()),
            ],
            vec![
                DiagnosticsHierarchy::new(
                    "child1",
                    vec![Property::Int("child1_sub".to_string(), 10i64)],
                    vec![],
                ),
                DiagnosticsHierarchy::new(
                    "child2",
                    vec![Property::Uint("child2_sub".to_string(), 20u64)],
                    vec![],
                ),
            ],
        )
    }

    fn non_unique_prop_tree() -> DiagnosticsHierarchy {
        DiagnosticsHierarchy::new(
            "key",
            vec![
                Property::String("prop".to_string(), "prop_value#0".to_string()),
                Property::String("prop".to_string(), "prop_value#1".to_string()),
            ],
            vec![],
        )
    }

    fn non_unique_child_tree() -> DiagnosticsHierarchy {
        DiagnosticsHierarchy::new(
            "key",
            vec![],
            vec![
                DiagnosticsHierarchy::new(
                    "child",
                    vec![Property::Int("prop".to_string(), 10i64)],
                    vec![],
                ),
                DiagnosticsHierarchy::new(
                    "child",
                    vec![Property::Int("prop".to_string(), 20i64)],
                    vec![],
                ),
            ],
        )
    }
}
