From 6408d2d5b445b75eda812e6d218ec98fa1e5bb31 Mon Sep 17 00:00:00 2001 From: Hayden Stainsby Date: Wed, 11 Jan 2023 17:45:37 +0100 Subject: [PATCH 1/7] mock: document public APIs in `span` module This change adds documentation to the span module and all the public APIs within it. This includes doctests on all the methods which serve as examples. Additionally, the validation on `ExpectedSpan` was improved so that it validates the level and target during `enter` and `exit` as well as on `new_span`. The method `ExpectedSpan::with_field` was renamed to `with_fields` (plural) to match the same method on `ExpectedEvent` (and because multiple fields can be passed to it). A copy-paste typo was also fixed in the documentation for `ExpectedEvent::with_contextual_parent`. Refs: #539 --- tracing-attributes/tests/async_fn.rs | 16 +- tracing-attributes/tests/destructuring.rs | 12 +- tracing-attributes/tests/err.rs | 2 +- tracing-attributes/tests/fields.rs | 18 +- tracing-attributes/tests/instrument.rs | 14 +- tracing-mock/README.md | 2 +- tracing-mock/src/collector.rs | 16 +- tracing-mock/src/event.rs | 2 +- tracing-mock/src/span.rs | 557 +++++++++++++++++- tracing-subscriber/tests/env_filter/main.rs | 4 +- .../tests/env_filter/per_subscriber.rs | 4 +- tracing-subscriber/tests/same_len_filters.rs | 4 +- tracing/tests/collector.rs | 4 +- tracing/tests/span.rs | 24 +- 14 files changed, 602 insertions(+), 77 deletions(-) diff --git a/tracing-attributes/tests/async_fn.rs b/tracing-attributes/tests/async_fn.rs index 38675a451a..74127c77fe 100644 --- a/tracing-attributes/tests/async_fn.rs +++ b/tracing-attributes/tests/async_fn.rs @@ -191,8 +191,8 @@ fn async_fn_with_async_trait() { let (collector, handle) = collector::mock() .new_span( span.clone() - .with_field(expect::field("self")) - .with_field(expect::field("v")), + .with_fields(expect::field("self")) + .with_fields(expect::field("v")), ) .enter(span.clone()) .new_span(span3.clone()) @@ -200,7 +200,7 @@ fn async_fn_with_async_trait() { .event(expect::event().with_fields(expect::field("val").with_value(&2u64))) .exit(span3.clone()) .drop_span(span3) - .new_span(span2.clone().with_field(expect::field("self"))) + .new_span(span2.clone().with_fields(expect::field("self"))) .enter(span2.clone()) .event(expect::event().with_fields(expect::field("val").with_value(&5u64))) .exit(span2.clone()) @@ -246,7 +246,7 @@ fn async_fn_with_async_trait_and_fields_expressions() { let span = expect::span().named("call"); let (collector, handle) = collector::mock() .new_span( - span.clone().with_field( + span.clone().with_fields( expect::field("_v") .with_value(&5usize) .and(expect::field("test").with_value(&tracing::field::debug(10))) @@ -314,7 +314,7 @@ fn async_fn_with_async_trait_and_fields_expressions_with_generic_parameter() { let span4 = expect::span().named("sync_fun"); let (collector, handle) = collector::mock() /*.new_span(span.clone() - .with_field( + .with_fields( expect::field("Self").with_value(&"TestImpler"))) .enter(span.clone()) .exit(span.clone()) @@ -322,13 +322,13 @@ fn async_fn_with_async_trait_and_fields_expressions_with_generic_parameter() { .new_span( span2 .clone() - .with_field(expect::field("Self").with_value(&std::any::type_name::())), + .with_fields(expect::field("Self").with_value(&std::any::type_name::())), ) .enter(span2.clone()) .new_span( span4 .clone() - .with_field(expect::field("Self").with_value(&std::any::type_name::())), + .with_fields(expect::field("Self").with_value(&std::any::type_name::())), ) .enter(span4.clone()) .exit(span4) @@ -337,7 +337,7 @@ fn async_fn_with_async_trait_and_fields_expressions_with_generic_parameter() { .new_span( span3 .clone() - .with_field(expect::field("Self").with_value(&std::any::type_name::())), + .with_fields(expect::field("Self").with_value(&std::any::type_name::())), ) .enter(span3.clone()) .exit(span3.clone()) diff --git a/tracing-attributes/tests/destructuring.rs b/tracing-attributes/tests/destructuring.rs index 3d7c88e8b6..6efccba31b 100644 --- a/tracing-attributes/tests/destructuring.rs +++ b/tracing-attributes/tests/destructuring.rs @@ -11,7 +11,7 @@ fn destructure_tuples() { let (collector, handle) = collector::mock() .new_span( - span.clone().with_field( + span.clone().with_fields( expect::field("arg1") .with_value(&format_args!("1")) .and(expect::field("arg2").with_value(&format_args!("2"))) @@ -40,7 +40,7 @@ fn destructure_nested_tuples() { let (collector, handle) = collector::mock() .new_span( - span.clone().with_field( + span.clone().with_fields( expect::field("arg1") .with_value(&format_args!("1")) .and(expect::field("arg2").with_value(&format_args!("2"))) @@ -72,7 +72,7 @@ fn destructure_refs() { let (collector, handle) = collector::mock() .new_span( span.clone() - .with_field(expect::field("arg1").with_value(&1usize).only()), + .with_fields(expect::field("arg1").with_value(&1usize).only()), ) .enter(span.clone()) .exit(span.clone()) @@ -98,7 +98,7 @@ fn destructure_tuple_structs() { let (collector, handle) = collector::mock() .new_span( - span.clone().with_field( + span.clone().with_fields( expect::field("arg1") .with_value(&format_args!("1")) .and(expect::field("arg2").with_value(&format_args!("2"))) @@ -139,7 +139,7 @@ fn destructure_structs() { let (collector, handle) = collector::mock() .new_span( - span.clone().with_field( + span.clone().with_fields( expect::field("arg1") .with_value(&format_args!("1")) .and(expect::field("arg2").with_value(&format_args!("2"))) @@ -184,7 +184,7 @@ fn destructure_everything() { let (collector, handle) = collector::mock() .new_span( - span.clone().with_field( + span.clone().with_fields( expect::field("arg1") .with_value(&format_args!("1")) .and(expect::field("arg2").with_value(&format_args!("2"))) diff --git a/tracing-attributes/tests/err.rs b/tracing-attributes/tests/err.rs index ffd30b3742..cfe2b340dd 100644 --- a/tracing-attributes/tests/err.rs +++ b/tracing-attributes/tests/err.rs @@ -155,7 +155,7 @@ fn impl_trait_return_type() { let (collector, handle) = collector::mock() .new_span( span.clone() - .with_field(expect::field("x").with_value(&10usize).only()), + .with_fields(expect::field("x").with_value(&10usize).only()), ) .enter(span.clone()) .exit(span.clone()) diff --git a/tracing-attributes/tests/fields.rs b/tracing-attributes/tests/fields.rs index b7b6fbeb1c..476d172482 100644 --- a/tracing-attributes/tests/fields.rs +++ b/tracing-attributes/tests/fields.rs @@ -46,7 +46,7 @@ impl HasField { #[test] fn fields() { - let span = expect::span().with_field( + let span = expect::span().with_fields( expect::field("foo") .with_value(&"bar") .and(expect::field("dsa").with_value(&true)) @@ -60,7 +60,7 @@ fn fields() { #[test] fn expr_field() { - let span = expect::span().with_field( + let span = expect::span().with_fields( expect::field("s") .with_value(&"hello world") .and(expect::field("len").with_value(&"hello world".len())) @@ -73,7 +73,7 @@ fn expr_field() { #[test] fn two_expr_fields() { - let span = expect::span().with_field( + let span = expect::span().with_fields( expect::field("s") .with_value(&"hello world") .and(expect::field("s.len").with_value(&"hello world".len())) @@ -87,7 +87,7 @@ fn two_expr_fields() { #[test] fn clashy_expr_field() { - let span = expect::span().with_field( + let span = expect::span().with_fields( // Overriding the `s` field should record `s` as a `Display` value, // rather than as a `Debug` value. expect::field("s") @@ -99,7 +99,7 @@ fn clashy_expr_field() { fn_clashy_expr_field("hello world"); }); - let span = expect::span().with_field(expect::field("s").with_value(&"s").only()); + let span = expect::span().with_fields(expect::field("s").with_value(&"s").only()); run_test(span, || { fn_clashy_expr_field2("hello world"); }); @@ -108,7 +108,7 @@ fn clashy_expr_field() { #[test] fn self_expr_field() { let span = - expect::span().with_field(expect::field("my_field").with_value(&"hello world").only()); + expect::span().with_fields(expect::field("my_field").with_value(&"hello world").only()); run_test(span, || { let has_field = HasField { my_field: "hello world", @@ -119,7 +119,7 @@ fn self_expr_field() { #[test] fn parameters_with_fields() { - let span = expect::span().with_field( + let span = expect::span().with_fields( expect::field("foo") .with_value(&"bar") .and(expect::field("param").with_value(&1u32)) @@ -132,7 +132,7 @@ fn parameters_with_fields() { #[test] fn empty_field() { - let span = expect::span().with_field(expect::field("foo").with_value(&"bar").only()); + let span = expect::span().with_fields(expect::field("foo").with_value(&"bar").only()); run_test(span, || { fn_empty_field(); }); @@ -140,7 +140,7 @@ fn empty_field() { #[test] fn string_field() { - let span = expect::span().with_field(expect::field("s").with_value(&"hello world").only()); + let span = expect::span().with_fields(expect::field("s").with_value(&"hello world").only()); run_test(span, || { fn_string(String::from("hello world")); }); diff --git a/tracing-attributes/tests/instrument.rs b/tracing-attributes/tests/instrument.rs index a512051656..5d95e2fba6 100644 --- a/tracing-attributes/tests/instrument.rs +++ b/tracing-attributes/tests/instrument.rs @@ -64,7 +64,7 @@ fn fields() { .with_target("my_target"); let (collector, handle) = collector::mock() .new_span( - span.clone().with_field( + span.clone().with_fields( expect::field("arg1") .with_value(&2usize) .and(expect::field("arg2").with_value(&false)) @@ -75,7 +75,7 @@ fn fields() { .exit(span.clone()) .drop_span(span) .new_span( - span2.clone().with_field( + span2.clone().with_fields( expect::field("arg1") .with_value(&3usize) .and(expect::field("arg2").with_value(&true)) @@ -115,7 +115,7 @@ fn skip() { let (collector, handle) = collector::mock() .new_span( span.clone() - .with_field(expect::field("arg1").with_value(&2usize).only()), + .with_fields(expect::field("arg1").with_value(&2usize).only()), ) .enter(span.clone()) .exit(span.clone()) @@ -123,7 +123,7 @@ fn skip() { .new_span( span2 .clone() - .with_field(expect::field("arg1").with_value(&3usize).only()), + .with_fields(expect::field("arg1").with_value(&3usize).only()), ) .enter(span2.clone()) .exit(span2.clone()) @@ -155,7 +155,7 @@ fn generics() { let (collector, handle) = collector::mock() .new_span( - span.clone().with_field( + span.clone().with_fields( expect::field("arg1") .with_value(&format_args!("Foo")) .and(expect::field("arg2").with_value(&format_args!("false"))), @@ -188,7 +188,7 @@ fn methods() { let (collector, handle) = collector::mock() .new_span( - span.clone().with_field( + span.clone().with_fields( expect::field("self") .with_value(&format_args!("Foo")) .and(expect::field("arg1").with_value(&42usize)), @@ -220,7 +220,7 @@ fn impl_trait_return_type() { let (collector, handle) = collector::mock() .new_span( span.clone() - .with_field(expect::field("x").with_value(&10usize).only()), + .with_fields(expect::field("x").with_value(&10usize).only()), ) .enter(span.clone()) .exit(span.clone()) diff --git a/tracing-mock/README.md b/tracing-mock/README.md index b508db00cb..3de7c695f0 100644 --- a/tracing-mock/README.md +++ b/tracing-mock/README.md @@ -121,7 +121,7 @@ let span = expect::span().named("yak_shaving"); let (collector, handle) = collector::mock() .new_span( span.clone() - .with_field(expect::field("number_of_yaks").with_value(&yak_count).only()), + .with_fields(expect::field("number_of_yaks").with_value(&yak_count).only()), ) .enter(span.clone()) .event( diff --git a/tracing-mock/src/collector.rs b/tracing-mock/src/collector.rs index c5f3a79f0b..c341c05a58 100644 --- a/tracing-mock/src/collector.rs +++ b/tracing-mock/src/collector.rs @@ -21,12 +21,18 @@ use tracing::{ Collect, Event, Metadata, }; -struct SpanState { +pub(crate) struct SpanState { name: &'static str, refs: usize, meta: &'static Metadata<'static>, } +impl SpanState { + pub(crate) fn metadata(&self) -> &'static Metadata<'static> { + self.meta + } +} + struct Running) -> bool> { spans: Mutex>, expected: Arc>>, @@ -329,9 +335,7 @@ where match self.expected.lock().unwrap().pop_front() { None => {} Some(Expect::Enter(ref expected_span)) => { - if let Some(name) = expected_span.name() { - assert_eq!(name, span.name); - } + expected_span.check(span, &self.name); } Some(ex) => ex.bad(&self.name, format_args!("entered span {:?}", span.name)), } @@ -354,9 +358,7 @@ where match self.expected.lock().unwrap().pop_front() { None => {} Some(Expect::Exit(ref expected_span)) => { - if let Some(name) = expected_span.name() { - assert_eq!(name, span.name); - } + expected_span.check(span, &self.name); let curr = self.current.lock().unwrap().pop(); assert_eq!( Some(id), diff --git a/tracing-mock/src/event.rs b/tracing-mock/src/event.rs index 34ed9288c5..3859808099 100644 --- a/tracing-mock/src/event.rs +++ b/tracing-mock/src/event.rs @@ -364,7 +364,7 @@ impl ExpectedEvent { /// /// # Examples /// - /// The explicit parent is matched by name: + /// The contextual parent is matched by name: /// /// ``` /// use tracing::collect::with_default; diff --git a/tracing-mock/src/span.rs b/tracing-mock/src/span.rs index 4f61f98038..6b9e603950 100644 --- a/tracing-mock/src/span.rs +++ b/tracing-mock/src/span.rs @@ -1,16 +1,131 @@ +//! Define expectations to match and validate spans. +//! +//! The [`ExpectedSpan`] and [`NewSpan`] structs define expectations +//! for spans to be matched by the mock collector API in the +//! [`collector`] module. +//! +//! Expected spans should be created with [`expect::span`] and a +//! chain of method calls to describe the assertions we wish to make +//! about the span. Subsequently, the expectations about the lifetime +//! of the span can be set on the [`MockCollector`]. +//! +//! # Examples +//! +//! ``` +//! use tracing_mock::{collector, expect}; +//! +//! let span = expect::span() +//! .named("interesting_span") +//! .at_level(tracing::Level::INFO); +//! +//! let (collector, handle) = collector::mock() +//! .enter(span.clone()) +//! .exit(span) +//! .run_with_handle(); +//! +//! tracing::collect::with_default(collector, || { +//! let span = tracing::info_span!("interesting_span"); +//! let _guard = span.enter(); +//! }); +//! +//! handle.assert_finished(); +//! ``` +//! +//! In the following more complex example, in addition to validating +//! the name and level of the span, we also validate its parent and +//! fields at the time of creation. +//! +//! ``` +//! use tracing_mock::{collector, expect}; +//! +//! let span = expect::span() +//! .named("interesting_span") +//! .at_level(tracing::Level::INFO); +//! let new_span = span +//! .clone() +//! .with_fields(expect::field("field.name").with_value(&"field_value")) +//! .with_explicit_parent(Some("parent_span")); +//! +//! let (collector, handle) = collector::mock() +//! .new_span(expect::span().named("parent_span")) +//! .new_span(new_span) +//! .enter(span.clone()) +//! .exit(span) +//! .run_with_handle(); +//! +//! tracing::collect::with_default(collector, || { +//! let parent = tracing::info_span!("parent_span"); +//! +//! let span = tracing::info_span!( +//! parent: parent.id(), +//! "interesting_span", +//! field.name = "field_value", +//! ); +//! let _guard = span.enter(); +//! }); +//! +//! handle.assert_finished(); +//! ``` +//! +//! The expectations must all be met for the validation to pass. For +//! example, if the span name is incorrect, the test will fail: +//! +//! ```should_panic +//! use tracing_mock::{collector, expect}; +//! +//! let span = expect::span() +//! .named("interesting_span") +//! .at_level(tracing::Level::INFO); +//! +//! let (collector, handle) = collector::mock() +//! .enter(span.clone()) +//! .exit(span) +//! .run_with_handle(); +//! +//! tracing::collect::with_default(collector, || { +//! let span = tracing::info_span!("another_span"); +//! let _guard = span.enter(); +//! }); +//! +//! handle.assert_finished(); +//! ``` +//! +//! [`MockCollector`]: struct@crate::collector::MockCollector +//! [`collector`]: mod@crate::collector +//! [`expect::span`]: fn@crate::expect::span #![allow(missing_docs)] -use super::{expect, field::ExpectedFields, metadata::ExpectedMetadata, Parent}; +use crate::{ + collector::SpanState, expect, field::ExpectedFields, metadata::ExpectedMetadata, Parent, +}; use std::fmt; /// A mock span. /// -/// This is intended for use with the mock subscriber API in the -/// `subscriber` module. +/// This is intended for use with the mock collector API in the +/// [`collector`] module. +/// +/// [`collector`]: mod@crate::collector #[derive(Clone, Default, Eq, PartialEq)] pub struct ExpectedSpan { pub(crate) metadata: ExpectedMetadata, } +/// A mock new span +/// +/// **Note**: This struct holds expectatoins that can only be validated +/// when expecting a new span via [`MockCollector::new_span`]. They +/// cannot be validated on [`MockCollector::enter`], +/// [`MockCollector::exit`], or any other method on [`MockCollector`] +/// that takes an `ExpectedSpan`. +/// +/// For more details on how to use this struct, see the documentation +/// on the [`collector`] module. +/// +/// [`collector`]: mod@crate::collector +/// [`MockCollector`]: struct@crate::collector::MockCollector +/// [`MockCollector::enter`]: fn@crate::collector::MockCollector::enter +/// [`MockCollector::exit`]: fn@crate::collector::MockCollector::exit +/// [`MockCollector::new_span`]: fn@crate::collector::MockCollector::new_span #[derive(Default, Eq, PartialEq)] pub struct NewSpan { pub(crate) span: ExpectedSpan, @@ -26,6 +141,48 @@ where } impl ExpectedSpan { + /// Sets a name to expect when matching a span. + /// + /// If an event is recorded with a name that doesn't match the + /// provided name, this expectation will fail. + /// + /// # Examples + /// + /// ``` + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span().named("span name"); + /// + /// let (collector, handle) = collector::mock() + /// .enter(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// let span = tracing::info_span!("span name"); + /// let _guard = span.enter(); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// When the span name is different, the test will fail: + /// + /// ```should_panic + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span().named("span name"); + /// + /// let (collector, handle) = collector::mock() + /// .enter(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// let span = tracing::info_span!("a different span name"); + /// let _guard = span.enter(); + /// }); + /// + /// handle.assert_finished(); + /// ``` pub fn named(self, name: I) -> Self where I: Into, @@ -38,6 +195,51 @@ impl ExpectedSpan { } } + /// Sets the [`Level`](tracing::Level) to expect when matching a span. + /// + /// If a span is recorded at a different level, this expectation + /// will fail. + /// + /// # Examples + /// + /// ``` + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span() + /// .at_level(tracing::Level::INFO); + /// + /// let (collector, handle) = collector::mock() + /// .enter(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// let span = tracing::info_span!("span"); + /// let _guard = span.enter(); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// Expecting a span at `INFO` level will fail if the event is + /// recorded at any other level: + /// + /// ```should_panic + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span() + /// .at_level(tracing::Level::INFO); + /// + /// let (collector, handle) = collector::mock() + /// .enter(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// let span = tracing::warn_span!("a serious span"); + /// let _guard = span.enter(); + /// }); + /// + /// handle.assert_finished(); + /// ``` pub fn at_level(self, level: tracing::Level) -> Self { Self { metadata: ExpectedMetadata { @@ -47,6 +249,50 @@ impl ExpectedSpan { } } + /// Sets the target to expect when matching a span. + /// + /// If a span is recorded with a different target, this expectation + /// will fail. + /// + /// # Examples + /// + /// ``` + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span() + /// .with_target("some_target"); + /// + /// let (collector, handle) = collector::mock() + /// .enter(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// let span = tracing::info_span!(target: "some_target", "span"); + /// let _guard = span.enter(); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// The test will fail if the target is different: + /// + /// ```should_panic + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span() + /// .with_target("some_target"); + /// + /// let (collector, handle) = collector::mock() + /// .enter(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// let span = tracing::info_span!(target: "a_different_target", "span"); + /// let _guard = span.enter(); + /// }); + /// + /// handle.assert_finished(); + /// ``` pub fn with_target(self, target: I) -> Self where I: Into, @@ -59,6 +305,101 @@ impl ExpectedSpan { } } + /// Configures this `ExpectedSpan` to expect an explicit parent + /// span or to be an explicit root. + /// + /// **Note**: This method returns a [`NewSpan`] and as such, this + /// expectation can only be validated when expecting a new span via + /// [`MockCollector::new_span`]. It cannot be validated on + /// [`MockCollector::enter`], [`MockCollector::exit`], or any other + /// method on [`MockCollector`] that takes an `ExpectedSpan`. + /// + /// An _explicit_ parent span is one passed to the `span!` macro in the + /// `parent:` field. + /// + /// If `Some("parent_name")` is passed to `with_explicit_parent` then + /// the provided string is the name of the parent span to expect. + /// + /// To expect that a span is recorded with `parent: None`, `None` + /// can be passed to `with_explicit_parent` instead. + /// + /// If a span is recorded without an explicit parent, or if the + /// explicit parent has a different name, this expectation will + /// fail. + /// + /// # Examples + /// + /// The explicit parent is matched by name: + /// + /// ``` + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span() + /// .with_explicit_parent(Some("parent_span")); + /// + /// let (collector, handle) = collector::mock() + /// .new_span(expect::span().named("parent_span")) + /// .new_span(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// let parent = tracing::info_span!("parent_span"); + /// tracing::info_span!(parent: parent.id(), "span"); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// In the following example, we expect that the matched span is + /// an explicit root: + /// + /// ``` + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span() + /// .with_explicit_parent(None); + /// + /// let (collector, handle) = collector::mock() + /// .new_span(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// tracing::info_span!(parent: None, "span"); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// In the example below, the expectation fails because the + /// span is contextually (rather than explicitly) within the span + /// `parent_span`: + /// + /// ```should_panic + /// use tracing_mock::{collector, expect}; + /// + /// let parent_span = expect::span().named("parent_span"); + /// let span = expect::span() + /// .with_explicit_parent(Some("parent_span")); + /// + /// let (collector, handle) = collector::mock() + /// .new_span(parent_span.clone()) + /// .enter(parent_span) + /// .new_span(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// let parent = tracing::info_span!("parent_span"); + /// let _guard = parent.enter(); + /// tracing::info_span!("span"); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// [`MockCollector`]: struct@crate::collector::MockCollector + /// [`MockCollector::enter`]: fn@crate::collector::MockCollector::enter + /// [`MockCollector::exit`]: fn@crate::collector::MockCollector::exit + /// [`MockCollector::new_span`]: fn@crate::collector::MockCollector::new_span pub fn with_explicit_parent(self, parent: Option<&str>) -> NewSpan { let parent = match parent { Some(name) => Parent::Explicit(name.into()), @@ -71,6 +412,99 @@ impl ExpectedSpan { } } + /// Configures this `ExpectedSpan` to expect a + /// contextually-determined parent span, or to be a contextual + /// root. + /// + /// **Note**: This method returns a [`NewSpan`] and as such, this + /// expectation can only be validated when expecting a new span via + /// [`MockCollector::new_span`]. It cannot be validated on + /// [`MockCollector::enter`], [`MockCollector::exit`], or any other + /// method on [`MockCollector`] that takes an `ExpectedSpan`. + /// + /// The provided string is the name of the parent span to expect. + /// To expect that the event is a contextually-determined root, pass + /// `None` instead. + /// + /// To expect a span with an explicit parent span, use + /// [`ExpectedSpan::with_explicit_parent`]. + /// + /// If a span is recorded which is not inside a span, has an explicitly + /// overridden parent span, or with a differently-named span as its + /// parent, this expectation will fail. + /// + /// # Examples + /// + /// The contextual parent is matched by name: + /// + /// ``` + /// use tracing_mock::{collector, expect}; + /// + /// let parent_span = expect::span().named("parent_span"); + /// let span = expect::span() + /// .with_contextual_parent(Some("parent_span")); + /// + /// let (collector, handle) = collector::mock() + /// .new_span(parent_span.clone()) + /// .enter(parent_span) + /// .new_span(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// let parent = tracing::info_span!("parent_span"); + /// let _guard = parent.enter(); + /// tracing::info_span!("span"); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// In the following example, we expect that the matched span is + /// a contextually-determined root: + /// + /// ``` + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span() + /// .with_contextual_parent(None); + /// + /// let (collector, handle) = collector::mock() + /// .new_span(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// tracing::info_span!("span"); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// In the example below, the expectation fails because the + /// span is recorded with an explicit parent: + /// + /// ```should_panic + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span() + /// .with_contextual_parent(Some("parent_span")); + /// + /// let (collector, handle) = collector::mock() + /// .new_span(expect::span().named("parent_span")) + /// .new_span(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// let parent = tracing::info_span!("parent_span"); + /// tracing::info_span!(parent: parent.id(), "span"); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// [`MockCollector`]: struct@crate::collector::MockCollector + /// [`MockCollector::enter`]: fn@crate::collector::MockCollector::enter + /// [`MockCollector::exit`]: fn@crate::collector::MockCollector::exit + /// [`MockCollector::new_span`]: fn@crate::collector::MockCollector::new_span pub fn with_contextual_parent(self, parent: Option<&str>) -> NewSpan { let parent = match parent { Some(name) => Parent::Contextual(name.into()), @@ -83,27 +517,95 @@ impl ExpectedSpan { } } - pub fn name(&self) -> Option<&str> { + /// Adds fields to expect when matching a span. + /// + /// **Note**: This method returns a [`NewSpan`] and as such, this + /// expectation can only be validated when expecting a new span via + /// [`MockCollector::new_span`]. It cannot be validated on + /// [`MockCollector::enter`], [`MockCollector::exit`], or any other + /// method on [`MockCollector`] that takes an `ExpectedSpan`. + /// + /// If a span is recorded with fields that do not match the provided + /// [`ExpectedFields`], this expectation will fail. + /// + /// If the provided field is not present on the recorded span, or + /// if the value for that field is different, then the expectation + /// will fail. + /// + /// More information on the available validations is available in + /// the [`ExpectedFields`] documentation. + /// + /// # Examples + /// + /// ``` + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span() + /// .with_fields(expect::field("field.name").with_value(&"field_value")); + /// + /// let (collector, handle) = collector::mock() + /// .new_span(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// tracing::info_span!("span", field.name = "field_value"); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// A different field value will cause the expectation to fail: + /// + /// ```should_panic + /// use tracing_mock::{collector, expect}; + /// + /// let span = expect::span() + /// .with_fields(expect::field("field.name").with_value(&"field_value")); + /// + /// let (collector, handle) = collector::mock() + /// .new_span(span) + /// .run_with_handle(); + /// + /// tracing::collect::with_default(collector, || { + /// tracing::info_span!("span", field.name = "different_field_value"); + /// }); + /// + /// handle.assert_finished(); + /// ``` + /// + /// [`ExpectedFields`]: struct@crate::field::ExpectedFields + /// [`MockCollector`]: struct@crate::collector::MockCollector + /// [`MockCollector::enter`]: fn@crate::collector::MockCollector::enter + /// [`MockCollector::exit`]: fn@crate::collector::MockCollector::exit + /// [`MockCollector::new_span`]: fn@crate::collector::MockCollector::new_span + pub fn with_fields(self, fields: I) -> NewSpan + where + I: Into, + { + NewSpan { + span: self, + fields: fields.into(), + ..Default::default() + } + } + + pub(crate) fn name(&self) -> Option<&str> { self.metadata.name.as_ref().map(String::as_ref) } - pub fn level(&self) -> Option { + pub(crate) fn level(&self) -> Option { self.metadata.level } - pub fn target(&self) -> Option<&str> { + pub(crate) fn target(&self) -> Option<&str> { self.metadata.target.as_deref() } - pub fn with_field(self, fields: I) -> NewSpan - where - I: Into, - { - NewSpan { - span: self, - fields: fields.into(), - ..Default::default() - } + pub(crate) fn check(&self, actual: &SpanState, collector_name: &str) { + let meta = actual.metadata(); + let name = meta.name(); + self.metadata + .check(meta, format_args!("span `{}`", name), collector_name); } } @@ -147,6 +649,13 @@ impl From for NewSpan { } impl NewSpan { + /// Configures this `ExpectedSpan` to expect an explicit parent + /// span or to be an explicit root. + /// + /// For more information and examples, see the documentation on + /// [`ExpectedSpan::with_explicit_parent`]. + /// + /// [`ExpectedSpan::with_explicit_parent`]: fn@crate::span::ExpectedSpan::with_explicit_parent pub fn with_explicit_parent(self, parent: Option<&str>) -> NewSpan { let parent = match parent { Some(name) => Parent::Explicit(name.into()), @@ -158,6 +667,14 @@ impl NewSpan { } } + /// Configures this `NewSpan` to expect a + /// contextually-determined parent span, or to be a contextual + /// root. + /// + /// For more information and examples, see the documentation on + /// [`ExpectedSpan::with_contextual_parent`]. + /// + /// [`ExpectedSpan::with_contextual_parent`]: fn@crate::span::ExpectedSpan::with_contextual_parent pub fn with_contextual_parent(self, parent: Option<&str>) -> NewSpan { let parent = match parent { Some(name) => Parent::Contextual(name.into()), @@ -169,7 +686,13 @@ impl NewSpan { } } - pub fn with_field(self, fields: I) -> NewSpan + /// Adds fields to expect when matching a span. + /// + /// For more information and examples, see the documentation on + /// [`ExpectedSpan::with_fields`]. + /// + /// [`ExpectedSpan::with_fields`]: fn@crate::span::ExpectedSpan::with_fields + pub fn with_fields(self, fields: I) -> NewSpan where I: Into, { @@ -179,7 +702,7 @@ impl NewSpan { } } - pub fn check( + pub(crate) fn check( &mut self, span: &tracing_core::span::Attributes<'_>, get_parent_name: impl FnOnce() -> Option, diff --git a/tracing-subscriber/tests/env_filter/main.rs b/tracing-subscriber/tests/env_filter/main.rs index 260da39a2d..47c4cabaf8 100644 --- a/tracing-subscriber/tests/env_filter/main.rs +++ b/tracing-subscriber/tests/env_filter/main.rs @@ -41,13 +41,13 @@ fn same_name_spans() { expect::span() .named("foo") .at_level(Level::TRACE) - .with_field(expect::field("bar")), + .with_fields(expect::field("bar")), ) .new_span( expect::span() .named("foo") .at_level(Level::TRACE) - .with_field(expect::field("baz")), + .with_fields(expect::field("baz")), ) .only() .run_with_handle(); diff --git a/tracing-subscriber/tests/env_filter/per_subscriber.rs b/tracing-subscriber/tests/env_filter/per_subscriber.rs index f86612aaab..8af97cbffe 100644 --- a/tracing-subscriber/tests/env_filter/per_subscriber.rs +++ b/tracing-subscriber/tests/env_filter/per_subscriber.rs @@ -37,13 +37,13 @@ fn same_name_spans() { expect::span() .named("foo") .at_level(Level::TRACE) - .with_field(expect::field("bar")), + .with_fields(expect::field("bar")), ) .new_span( expect::span() .named("foo") .at_level(Level::TRACE) - .with_field(expect::field("baz")), + .with_fields(expect::field("baz")), ) .only() .run_with_handle(); diff --git a/tracing-subscriber/tests/same_len_filters.rs b/tracing-subscriber/tests/same_len_filters.rs index 53f1793b42..d3f39509e2 100644 --- a/tracing-subscriber/tests/same_len_filters.rs +++ b/tracing-subscriber/tests/same_len_filters.rs @@ -61,13 +61,13 @@ fn same_num_fields_and_name_len() { expect::span() .named("foo") .at_level(Level::TRACE) - .with_field(expect::field("bar")), + .with_fields(expect::field("bar")), ) .new_span( expect::span() .named("baz") .at_level(Level::TRACE) - .with_field(expect::field("boz")), + .with_fields(expect::field("boz")), ) .only() .run_with_handle(); diff --git a/tracing/tests/collector.rs b/tracing/tests/collector.rs index d5cccc245e..48b1aa1e53 100644 --- a/tracing/tests/collector.rs +++ b/tracing/tests/collector.rs @@ -64,7 +64,7 @@ fn event_macros_dont_infinite_loop() { fn boxed_collector() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("foo").with_field( + expect::span().named("foo").with_fields( expect::field("bar") .with_value(&display("hello from my span")) .only(), @@ -97,7 +97,7 @@ fn arced_collector() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("foo").with_field( + expect::span().named("foo").with_fields( expect::field("bar") .with_value(&display("hello from my span")) .only(), diff --git a/tracing/tests/span.rs b/tracing/tests/span.rs index ad71b17a8c..db38256006 100644 --- a/tracing/tests/span.rs +++ b/tracing/tests/span.rs @@ -337,7 +337,7 @@ fn entered_api() { fn moved_field() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("foo").with_field( + expect::span().named("foo").with_fields( expect::field("bar") .with_value(&display("hello from my span")) .only(), @@ -368,7 +368,7 @@ fn dotted_field_name() { .new_span( expect::span() .named("foo") - .with_field(expect::field("fields.bar").with_value(&true).only()), + .with_fields(expect::field("fields.bar").with_value(&true).only()), ) .only() .run_with_handle(); @@ -384,7 +384,7 @@ fn dotted_field_name() { fn borrowed_field() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("foo").with_field( + expect::span().named("foo").with_fields( expect::field("bar") .with_value(&display("hello from my span")) .only(), @@ -427,7 +427,7 @@ fn move_field_out_of_struct() { }; let (collector, handle) = collector::mock() .new_span( - expect::span().named("foo").with_field( + expect::span().named("foo").with_fields( expect::field("x") .with_value(&debug(3.234)) .and(expect::field("y").with_value(&debug(-1.223))) @@ -437,7 +437,7 @@ fn move_field_out_of_struct() { .new_span( expect::span() .named("bar") - .with_field(expect::field("position").with_value(&debug(&pos)).only()), + .with_fields(expect::field("position").with_value(&debug(&pos)).only()), ) .run_with_handle(); @@ -460,7 +460,7 @@ fn move_field_out_of_struct() { fn float_values() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("foo").with_field( + expect::span().named("foo").with_fields( expect::field("x") .with_value(&3.234) .and(expect::field("y").with_value(&-1.223)) @@ -487,7 +487,7 @@ fn add_field_after_new_span() { .new_span( span::mock() .named("foo") - .with_field(expect::field("bar").with_value(&5) + .with_fields(expect::field("bar").with_value(&5) .and(expect::field("baz").with_value).only()), ) .record( @@ -544,7 +544,7 @@ fn add_fields_only_after_new_span() { fn record_new_value_for_field() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("foo").with_field( + expect::span().named("foo").with_fields( expect::field("bar") .with_value(&5) .and(expect::field("baz").with_value(&false)) @@ -575,7 +575,7 @@ fn record_new_value_for_field() { fn record_new_values_for_fields() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("foo").with_field( + expect::span().named("foo").with_fields( expect::field("bar") .with_value(&4) .and(expect::field("baz").with_value(&false)) @@ -776,7 +776,7 @@ fn contextual_child() { fn display_shorthand() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("my_span").with_field( + expect::span().named("my_span").with_fields( expect::field("my_field") .with_value(&display("hello world")) .only(), @@ -796,7 +796,7 @@ fn display_shorthand() { fn debug_shorthand() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("my_span").with_field( + expect::span().named("my_span").with_fields( expect::field("my_field") .with_value(&debug("hello world")) .only(), @@ -816,7 +816,7 @@ fn debug_shorthand() { fn both_shorthands() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("my_span").with_field( + expect::span().named("my_span").with_fields( expect::field("display_field") .with_value(&display("hello world")) .and(expect::field("debug_field").with_value(&debug("hello world"))) From 7e4c9500e2f4a3c4e12325e87ec9112aa893c09a Mon Sep 17 00:00:00 2001 From: Hayden Stainsby Date: Mon, 30 Jan 2023 18:25:55 +0100 Subject: [PATCH 2/7] rename `Span::with_field` to `Span::with_fields` in subscriber docs --- tracing-mock/src/subscriber.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracing-mock/src/subscriber.rs b/tracing-mock/src/subscriber.rs index e923f56863..b0686f74b8 100644 --- a/tracing-mock/src/subscriber.rs +++ b/tracing-mock/src/subscriber.rs @@ -432,7 +432,7 @@ impl MockSubscriberBuilder { /// let span = expect::span() /// .at_level(tracing::Level::INFO) /// .named("the span we're testing") - /// .with_field(expect::field("testing").with_value(&"yes")); + /// .with_fields(expect::field("testing").with_value(&"yes")); /// let (subscriber, handle) = subscriber::mock() /// .new_span(span) /// .run_with_handle(); @@ -456,7 +456,7 @@ impl MockSubscriberBuilder { /// let span = expect::span() /// .at_level(tracing::Level::INFO) /// .named("the span we're testing") - /// .with_field(expect::field("testing").with_value(&"yes")); + /// .with_fields(expect::field("testing").with_value(&"yes")); /// let (subscriber, handle) = subscriber::mock() /// .new_span(span) /// .run_with_handle(); From 1860f6a9e9137b8a46f1a924b7ef1764f9f70eba Mon Sep 17 00:00:00 2001 From: Hayden Stainsby Date: Mon, 26 Jun 2023 12:50:34 +0200 Subject: [PATCH 3/7] Fix collector doctests The collector doctests needed to be updated to take into consideration the newly renamed method `ExpectedSpan::with_fields` (was `with_field`). --- tracing-mock/src/collector.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracing-mock/src/collector.rs b/tracing-mock/src/collector.rs index c126e9bba2..d1f05a24eb 100644 --- a/tracing-mock/src/collector.rs +++ b/tracing-mock/src/collector.rs @@ -405,7 +405,7 @@ where /// let span = expect::span() /// .at_level(tracing::Level::INFO) /// .named("the span we're testing") - /// .with_field(expect::field("testing").with_value(&"yes")); + /// .with_fields(expect::field("testing").with_value(&"yes")); /// let (collector, handle) = collector::mock() /// .new_span(span) /// .run_with_handle(); @@ -426,7 +426,7 @@ where /// let span = expect::span() /// .at_level(tracing::Level::INFO) /// .named("the span we're testing") - /// .with_field(expect::field("testing").with_value(&"yes")); + /// .with_fields(expect::field("testing").with_value(&"yes")); /// let (collector, handle) = collector::mock() /// .new_span(span) /// .run_with_handle(); From 006a4f010479d7b025ebc5ef5ed1c367bcb8cf15 Mon Sep 17 00:00:00 2001 From: Hayden Stainsby Date: Wed, 25 Oct 2023 14:20:03 +0200 Subject: [PATCH 4/7] adapt new test to `.with_fields()` method --- tracing/tests/span.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracing/tests/span.rs b/tracing/tests/span.rs index d03a439909..e2c4c92396 100644 --- a/tracing/tests/span.rs +++ b/tracing/tests/span.rs @@ -842,7 +842,7 @@ fn both_shorthands() { fn constant_field_name() { let (collector, handle) = collector::mock() .new_span( - expect::span().named("my_span").with_field( + expect::span().named("my_span").with_fields( expect::field("foo") .with_value(&"bar") .and(expect::field("constant string").with_value(&"also works")) From ee7154bc5348a4e55b4af11fa2a17256343794ef Mon Sep 17 00:00:00 2001 From: Hayden Stainsby Date: Thu, 26 Oct 2023 10:26:48 +0200 Subject: [PATCH 5/7] Apply suggestions from code review Co-authored-by: David Barsky --- tracing-mock/src/span.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tracing-mock/src/span.rs b/tracing-mock/src/span.rs index 6b9e603950..778bae234c 100644 --- a/tracing-mock/src/span.rs +++ b/tracing-mock/src/span.rs @@ -5,9 +5,8 @@ //! [`collector`] module. //! //! Expected spans should be created with [`expect::span`] and a -//! chain of method calls to describe the assertions we wish to make -//! about the span. Subsequently, the expectations about the lifetime -//! of the span can be set on the [`MockCollector`]. +//! chain of method calls describing the assertions made about the +//! span. Expectations about the lifecycle of the span can be set on the [`MockCollector`]. //! //! # Examples //! @@ -31,9 +30,7 @@ //! handle.assert_finished(); //! ``` //! -//! In the following more complex example, in addition to validating -//! the name and level of the span, we also validate its parent and -//! fields at the time of creation. +//! The following example asserts the name, level, parent, and fields of the span: //! //! ``` //! use tracing_mock::{collector, expect}; @@ -67,8 +64,8 @@ //! handle.assert_finished(); //! ``` //! -//! The expectations must all be met for the validation to pass. For -//! example, if the span name is incorrect, the test will fail: +//! All expectations must be met for the test to pass. For example, +//! the following test will fail due to a mismatch in the spans' names: //! //! ```should_panic //! use tracing_mock::{collector, expect}; @@ -84,7 +81,7 @@ //! //! tracing::collect::with_default(collector, || { //! let span = tracing::info_span!("another_span"); -//! let _guard = span.enter(); +//! let _guard = span.enter(); //! }); //! //! handle.assert_finished(); From 04b3c09b733e46ac5a4dca88a62a1b0e23607884 Mon Sep 17 00:00:00 2001 From: Hayden Stainsby Date: Tue, 31 Oct 2023 10:55:55 +0100 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: David Barsky --- tracing-mock/src/span.rs | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/tracing-mock/src/span.rs b/tracing-mock/src/span.rs index 778bae234c..0d22dcb81f 100644 --- a/tracing-mock/src/span.rs +++ b/tracing-mock/src/span.rs @@ -107,10 +107,10 @@ pub struct ExpectedSpan { pub(crate) metadata: ExpectedMetadata, } -/// A mock new span +/// A mock new span. /// -/// **Note**: This struct holds expectatoins that can only be validated -/// when expecting a new span via [`MockCollector::new_span`]. They +/// **Note**: This struct contains expectations that can only be asserted +/// on when expecting a new span via [`MockCollector::new_span`]. They /// cannot be validated on [`MockCollector::enter`], /// [`MockCollector::exit`], or any other method on [`MockCollector`] /// that takes an `ExpectedSpan`. @@ -140,8 +140,7 @@ where impl ExpectedSpan { /// Sets a name to expect when matching a span. /// - /// If an event is recorded with a name that doesn't match the - /// provided name, this expectation will fail. + /// If an event is recorded with a name that differs from the one provided to this method, the expectation will fail. /// /// # Examples /// @@ -162,7 +161,7 @@ impl ExpectedSpan { /// handle.assert_finished(); /// ``` /// - /// When the span name is different, the test will fail: + /// When the span name is different, the assertion will fail: /// /// ```should_panic /// use tracing_mock::{collector, expect}; @@ -194,8 +193,7 @@ impl ExpectedSpan { /// Sets the [`Level`](tracing::Level) to expect when matching a span. /// - /// If a span is recorded at a different level, this expectation - /// will fail. + /// If an span is record with a level that differs from the one provided to this method, the expectation will fail. /// /// # Examples /// @@ -314,10 +312,10 @@ impl ExpectedSpan { /// An _explicit_ parent span is one passed to the `span!` macro in the /// `parent:` field. /// - /// If `Some("parent_name")` is passed to `with_explicit_parent` then + /// If `Some("parent_name")` is passed to `with_explicit_parent` then, /// the provided string is the name of the parent span to expect. /// - /// To expect that a span is recorded with `parent: None`, `None` + /// To expect that a span is recorded with no parent, `None` /// can be passed to `with_explicit_parent` instead. /// /// If a span is recorded without an explicit parent, or if the @@ -347,8 +345,7 @@ impl ExpectedSpan { /// handle.assert_finished(); /// ``` /// - /// In the following example, we expect that the matched span is - /// an explicit root: + /// In the following example, the expected span is an explicit root: /// /// ``` /// use tracing_mock::{collector, expect}; @@ -368,7 +365,7 @@ impl ExpectedSpan { /// ``` /// /// In the example below, the expectation fails because the - /// span is contextually (rather than explicitly) within the span + /// span is *contextually*—as opposed to explicitly—within the span /// `parent_span`: /// /// ```should_panic @@ -410,7 +407,7 @@ impl ExpectedSpan { } /// Configures this `ExpectedSpan` to expect a - /// contextually-determined parent span, or to be a contextual + /// contextually-determined parent span, or be a contextual /// root. /// /// **Note**: This method returns a [`NewSpan`] and as such, this @@ -427,7 +424,7 @@ impl ExpectedSpan { /// [`ExpectedSpan::with_explicit_parent`]. /// /// If a span is recorded which is not inside a span, has an explicitly - /// overridden parent span, or with a differently-named span as its + /// overridden parent span, or has a differently-named span as its /// parent, this expectation will fail. /// /// # Examples @@ -525,8 +522,8 @@ impl ExpectedSpan { /// If a span is recorded with fields that do not match the provided /// [`ExpectedFields`], this expectation will fail. /// - /// If the provided field is not present on the recorded span, or - /// if the value for that field is different, then the expectation + /// If the provided field is not present on the recorded span or + /// if the value for that field diffs, then the expectation /// will fail. /// /// More information on the available validations is available in From a8d52cfacb8507c5e31ccda80d68b792e142caba Mon Sep 17 00:00:00 2001 From: Hayden Stainsby Date: Tue, 14 Nov 2023 00:13:26 +0100 Subject: [PATCH 7/7] adjusted docs on `ExpectedSpan::with_target` as per review --- tracing-mock/src/span.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracing-mock/src/span.rs b/tracing-mock/src/span.rs index 0d22dcb81f..42ed3a603e 100644 --- a/tracing-mock/src/span.rs +++ b/tracing-mock/src/span.rs @@ -246,8 +246,8 @@ impl ExpectedSpan { /// Sets the target to expect when matching a span. /// - /// If a span is recorded with a different target, this expectation - /// will fail. + /// If an event is recorded with a target that doesn't match the + /// provided target, this expectation will fail. /// /// # Examples ///