1 use tracing::{subscriber::with_default, Id, Level, Span};
2 use tracing_attributes::instrument;
3 use tracing_mock::*;
4 
5 #[instrument(follows_from = causes, skip(causes))]
with_follows_from_sync(causes: impl IntoIterator<Item = impl Into<Option<Id>>>)6 fn with_follows_from_sync(causes: impl IntoIterator<Item = impl Into<Option<Id>>>) {}
7 
8 #[instrument(follows_from = causes, skip(causes))]
with_follows_from_async(causes: impl IntoIterator<Item = impl Into<Option<Id>>>)9 async fn with_follows_from_async(causes: impl IntoIterator<Item = impl Into<Option<Id>>>) {}
10 
11 #[instrument(follows_from = [&Span::current()])]
follows_from_current()12 fn follows_from_current() {}
13 
14 #[test]
follows_from_sync_test()15 fn follows_from_sync_test() {
16     let cause_a = expect::span().named("cause_a");
17     let cause_b = expect::span().named("cause_b");
18     let cause_c = expect::span().named("cause_c");
19     let consequence = expect::span().named("with_follows_from_sync");
20 
21     let (subscriber, handle) = subscriber::mock()
22         .new_span(cause_a.clone())
23         .new_span(cause_b.clone())
24         .new_span(cause_c.clone())
25         .new_span(consequence.clone())
26         .follows_from(consequence.clone(), cause_a)
27         .follows_from(consequence.clone(), cause_b)
28         .follows_from(consequence.clone(), cause_c)
29         .enter(consequence.clone())
30         .exit(consequence)
31         .only()
32         .run_with_handle();
33 
34     with_default(subscriber, || {
35         let cause_a = tracing::span!(Level::TRACE, "cause_a");
36         let cause_b = tracing::span!(Level::TRACE, "cause_b");
37         let cause_c = tracing::span!(Level::TRACE, "cause_c");
38 
39         with_follows_from_sync(&[cause_a, cause_b, cause_c])
40     });
41 
42     handle.assert_finished();
43 }
44 
45 #[test]
follows_from_async_test()46 fn follows_from_async_test() {
47     let cause_a = expect::span().named("cause_a");
48     let cause_b = expect::span().named("cause_b");
49     let cause_c = expect::span().named("cause_c");
50     let consequence = expect::span().named("with_follows_from_async");
51 
52     let (subscriber, handle) = subscriber::mock()
53         .new_span(cause_a.clone())
54         .new_span(cause_b.clone())
55         .new_span(cause_c.clone())
56         .new_span(consequence.clone())
57         .follows_from(consequence.clone(), cause_a)
58         .follows_from(consequence.clone(), cause_b)
59         .follows_from(consequence.clone(), cause_c)
60         .enter(consequence.clone())
61         .exit(consequence.clone())
62         .enter(consequence.clone())
63         .exit(consequence)
64         .only()
65         .run_with_handle();
66 
67     with_default(subscriber, || {
68         block_on_future(async {
69             let cause_a = tracing::span!(Level::TRACE, "cause_a");
70             let cause_b = tracing::span!(Level::TRACE, "cause_b");
71             let cause_c = tracing::span!(Level::TRACE, "cause_c");
72 
73             with_follows_from_async(&[cause_a, cause_b, cause_c]).await
74         })
75     });
76 
77     handle.assert_finished();
78 }
79 
80 #[test]
follows_from_current_test()81 fn follows_from_current_test() {
82     let cause = expect::span().named("cause");
83     let consequence = expect::span().named("follows_from_current");
84 
85     let (subscriber, handle) = subscriber::mock()
86         .new_span(cause.clone())
87         .enter(cause.clone())
88         .new_span(consequence.clone())
89         .follows_from(consequence.clone(), cause.clone())
90         .enter(consequence.clone())
91         .exit(consequence)
92         .exit(cause)
93         .only()
94         .run_with_handle();
95 
96     with_default(subscriber, || {
97         tracing::span!(Level::TRACE, "cause").in_scope(follows_from_current)
98     });
99 
100     handle.assert_finished();
101 }
102