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