Skip to content

Commit 5daa282

Browse files
committed
mock: improve ergonomics when an ExpectedSpan is needed
Many of the methods on `MockCollector` take an `ExpectedSpan`. This often requires significant boilerplate. For example, to expect that a span with a specific name enters and then exits, the following code is needed: ```rust let span = expect::span().named("span name"); let (collector, handle) = collector::mock() .enter(span.clone()) .exit(span) .run_with_handle(); ``` In order to make using `tracing-mock` more ergonomic and also more compact, the `MockCollector` and `MockSubscriber` methods that previous took an `ExpectedSpan`, are now generic over `Into<ExpectedSpan>`. There are currently 3 implementations of `From` for `ExpectedSpan` which allow the following shorthand uses: `T: Into<String>` - an `ExpectedSpan` will be created that expects to have a name specified by `T`. ```rust let (collector, handle) = collector::mock() .enter("span name") .exit("span name") .run_with_handle(); ``` `&ExpectedId` - an `ExpectedSpan` will be created that expects to have the expected Id. A reference is taken and cloned internally because the caller always needs to use an `ExpectedId` in at least 2 calls to the mock collector/subscriber. ```rust let id = expect::id(); let (collector, handle) = collector::mock() .new_span(&id) .enter(&id) .run_with_handle(); ``` `&ExpectedSpan` - The expected span is taken by reference and cloned. ```rust let span = expect::span().named("span name"); let (collector, handle) = collector::mock() .enter(&span) .exit(&span) .run_with_handle(); ``` In Rust, taking a reference to an object and immediately cloning it is an anti-pattern. It is considered better to force the user to clone outside the API to make the cloning explict. However, in the case of a testing framework, it seems reasonable to prefer a more concise API, rather than having it more explicit. To reduce the size of this PR and to avoid unnecessary churn in other crates, the tests within the tracing repo which use `tracing-mock` will not be updated to use the new `Into<ExpectedSpan>` capabilities. The new API is backwards compatible and those tests can remain as they are.
1 parent 2d30094 commit 5daa282

File tree

3 files changed

+188
-68
lines changed

3 files changed

+188
-68
lines changed

tracing-mock/src/collector.rs

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@
3838
//! .named("my_span");
3939
//! let (collector, handle) = collector::mock()
4040
//! // Enter a matching span
41-
//! .enter(span.clone())
41+
//! .enter(&span)
4242
//! // Record an event with message "collect parting message"
4343
//! .event(expect::event().with_fields(expect::message("collect parting message")))
4444
//! // Record a value for the field `parting` on a matching span
45-
//! .record(span.clone(), expect::field("parting").with_value(&"goodbye world!"))
45+
//! .record(&span, expect::field("parting").with_value(&"goodbye world!"))
4646
//! // Exit a matching span
4747
//! .exit(span)
4848
//! // Expect no further messages to be recorded
@@ -80,9 +80,9 @@
8080
//! let span = expect::span()
8181
//! .named("my_span");
8282
//! let (collector, handle) = collector::mock()
83-
//! .enter(span.clone())
83+
//! .enter(&span)
8484
//! .event(expect::event().with_fields(expect::message("collect parting message")))
85-
//! .record(span.clone(), expect::field("parting").with_value(&"goodbye world!"))
85+
//! .record(&span, expect::field("parting").with_value(&"goodbye world!"))
8686
//! .exit(span)
8787
//! .only()
8888
//! .run_with_handle();
@@ -225,11 +225,11 @@ pub struct MockHandle(Arc<Mutex<VecDeque<Expect>>>, String);
225225
/// .named("my_span");
226226
/// let (collector, handle) = collector::mock()
227227
/// // Enter a matching span
228-
/// .enter(span.clone())
228+
/// .enter(&span)
229229
/// // Record an event with message "collect parting message"
230230
/// .event(expect::event().with_fields(expect::message("collect parting message")))
231231
/// // Record a value for the field `parting` on a matching span
232-
/// .record(span.clone(), expect::field("parting").with_value(&"goodbye world!"))
232+
/// .record(&span, expect::field("parting").with_value(&"goodbye world!"))
233233
/// // Exit a matching span
234234
/// .exit(span)
235235
/// // Expect no further messages to be recorded
@@ -472,8 +472,8 @@ where
472472
/// .at_level(tracing::Level::INFO)
473473
/// .named("the span we're testing");
474474
/// let (collector, handle) = collector::mock()
475-
/// .enter(span.clone())
476-
/// .exit(span)
475+
/// .enter(&span)
476+
/// .exit(&span)
477477
/// .only()
478478
/// .run_with_handle();
479479
///
@@ -495,8 +495,8 @@ where
495495
/// .at_level(tracing::Level::INFO)
496496
/// .named("the span we're testing");
497497
/// let (collector, handle) = collector::mock()
498-
/// .enter(span.clone())
499-
/// .exit(span)
498+
/// .enter(&span)
499+
/// .exit(&span)
500500
/// .only()
501501
/// .run_with_handle();
502502
///
@@ -511,8 +511,11 @@ where
511511
///
512512
/// [`exit`]: fn@Self::exit
513513
/// [`only`]: fn@Self::only
514-
pub fn enter(mut self, span: ExpectedSpan) -> Self {
515-
self.expected.push_back(Expect::Enter(span));
514+
pub fn enter<S>(mut self, span: S) -> Self
515+
where
516+
S: Into<ExpectedSpan>,
517+
{
518+
self.expected.push_back(Expect::Enter(span.into()));
516519
self
517520
}
518521

@@ -536,8 +539,8 @@ where
536539
/// .at_level(tracing::Level::INFO)
537540
/// .named("the span we're testing");
538541
/// let (collector, handle) = collector::mock()
539-
/// .enter(span.clone())
540-
/// .exit(span)
542+
/// .enter(&span)
543+
/// .exit(&span)
541544
/// .run_with_handle();
542545
///
543546
/// tracing::collect::with_default(collector, || {
@@ -558,8 +561,8 @@ where
558561
/// .at_level(tracing::Level::INFO)
559562
/// .named("the span we're testing");
560563
/// let (collector, handle) = collector::mock()
561-
/// .enter(span.clone())
562-
/// .exit(span)
564+
/// .enter(&span)
565+
/// .exit(&span)
563566
/// .run_with_handle();
564567
///
565568
/// tracing::collect::with_default(collector, || {
@@ -572,8 +575,11 @@ where
572575
/// ```
573576
///
574577
/// [`enter`]: fn@Self::enter
575-
pub fn exit(mut self, span: ExpectedSpan) -> Self {
576-
self.expected.push_back(Expect::Exit(span));
578+
pub fn exit<S>(mut self, span: S) -> Self
579+
where
580+
S: Into<ExpectedSpan>,
581+
{
582+
self.expected.push_back(Expect::Exit(span.into()));
577583
self
578584
}
579585

@@ -627,8 +633,11 @@ where
627633
///
628634
/// handle.assert_finished();
629635
/// ```
630-
pub fn clone_span(mut self, span: ExpectedSpan) -> Self {
631-
self.expected.push_back(Expect::CloneSpan(span));
636+
pub fn clone_span<S>(mut self, span: S) -> Self
637+
where
638+
S: Into<ExpectedSpan>,
639+
{
640+
self.expected.push_back(Expect::CloneSpan(span.into()));
632641
self
633642
}
634643

@@ -644,8 +653,11 @@ where
644653
///
645654
/// [`Collect::drop_span`]: fn@tracing::Collect::drop_span
646655
#[allow(deprecated)]
647-
pub fn drop_span(mut self, span: ExpectedSpan) -> Self {
648-
self.expected.push_back(Expect::DropSpan(span));
656+
pub fn drop_span<S>(mut self, span: S) -> Self
657+
where
658+
S: Into<ExpectedSpan>,
659+
{
660+
self.expected.push_back(Expect::DropSpan(span.into()));
649661
self
650662
}
651663

@@ -710,9 +722,15 @@ where
710722
/// ```
711723
///
712724
/// [`Span::follows_from`]: fn@tracing::Span::follows_from
713-
pub fn follows_from(mut self, consequence: ExpectedSpan, cause: ExpectedSpan) -> Self {
714-
self.expected
715-
.push_back(Expect::FollowsFrom { consequence, cause });
725+
pub fn follows_from<S1, S2>(mut self, consequence: S1, cause: S2) -> Self
726+
where
727+
S1: Into<ExpectedSpan>,
728+
S2: Into<ExpectedSpan>,
729+
{
730+
self.expected.push_back(Expect::FollowsFrom {
731+
consequence: consequence.into(),
732+
cause: cause.into(),
733+
});
716734
self
717735
}
718736

@@ -775,11 +793,13 @@ where
775793
/// ```
776794
///
777795
/// [`field`]: mod@crate::field
778-
pub fn record<I>(mut self, span: ExpectedSpan, fields: I) -> Self
796+
pub fn record<S, I>(mut self, span: S, fields: I) -> Self
779797
where
798+
S: Into<ExpectedSpan>,
780799
I: Into<ExpectedFields>,
781800
{
782-
self.expected.push_back(Expect::Visit(span, fields.into()));
801+
self.expected
802+
.push_back(Expect::Visit(span.into(), fields.into()));
783803
self
784804
}
785805

0 commit comments

Comments
 (0)