1use std::convert::TryFrom;
2use std::num::TryFromIntError;
3use tracing_mock::*;
4
5use tracing::{subscriber::with_default, Level};
6use tracing_attributes::instrument;
7use tracing_subscriber::layer::SubscriberExt;
8use tracing_subscriber::EnvFilter;
9
10#[instrument(ret)]
11fn ret() -> i32 {
12 42
13}
14
15#[instrument(target = "my_target", ret)]
16fn ret_with_target() -> i32 {
17 42
18}
19
20#[test]
21fn test() {
22 let span = expect::span().named("ret");
23 let (subscriber, handle) = subscriber::mock()
24 .new_span(span.clone())
25 .enter(span.clone())
26 .event(
27 expect::event()
28 .with_fields(expect::field("return").with_value(&tracing::field::debug(42)))
29 .at_level(Level::INFO),
30 )
31 .exit(span.clone())
32 .drop_span(span)
33 .only()
34 .run_with_handle();
35
36 with_default(subscriber, ret);
37 handle.assert_finished();
38}
39
40#[test]
41fn test_custom_target() {
42 let filter: EnvFilter = "my_target=info".parse().expect("filter should parse");
43 let span = expect::span()
44 .named("ret_with_target")
45 .with_target("my_target");
46
47 let (subscriber, handle) = subscriber::mock()
48 .new_span(span.clone())
49 .enter(span.clone())
50 .event(
51 expect::event()
52 .with_fields(expect::field("return").with_value(&tracing::field::debug(42)))
53 .at_level(Level::INFO)
54 .with_target("my_target"),
55 )
56 .exit(span.clone())
57 .drop_span(span)
58 .only()
59 .run_with_handle();
60
61 let subscriber = subscriber.with(filter);
62
63 with_default(subscriber, ret_with_target);
64 handle.assert_finished();
65}
66
67#[instrument(level = "warn", ret)]
68fn ret_warn() -> i32 {
69 42
70}
71
72#[test]
73fn test_warn() {
74 let span = expect::span().named("ret_warn");
75 let (subscriber, handle) = subscriber::mock()
76 .new_span(span.clone())
77 .enter(span.clone())
78 .event(
79 expect::event()
80 .with_fields(expect::field("return").with_value(&tracing::field::debug(42)))
81 .at_level(Level::WARN),
82 )
83 .exit(span.clone())
84 .drop_span(span)
85 .only()
86 .run_with_handle();
87
88 with_default(subscriber, ret_warn);
89 handle.assert_finished();
90}
91
92#[instrument(ret)]
93fn ret_mut(a: &mut i32) -> i32 {
94 *a *= 2;
95 tracing::info!(?a);
96 *a
97}
98
99#[test]
100fn test_mut() {
101 let span = expect::span().named("ret_mut");
102 let (subscriber, handle) = subscriber::mock()
103 .new_span(span.clone())
104 .enter(span.clone())
105 .event(
106 expect::event()
107 .with_fields(expect::field("a").with_value(&tracing::field::display(2)))
108 .at_level(Level::INFO),
109 )
110 .event(
111 expect::event()
112 .with_fields(expect::field("return").with_value(&tracing::field::debug(2)))
113 .at_level(Level::INFO),
114 )
115 .exit(span.clone())
116 .drop_span(span)
117 .only()
118 .run_with_handle();
119
120 with_default(subscriber, || ret_mut(&mut 1));
121 handle.assert_finished();
122}
123
124#[instrument(ret)]
125async fn ret_async() -> i32 {
126 42
127}
128
129#[test]
130fn test_async() {
131 let span = expect::span().named("ret_async");
132 let (subscriber, handle) = subscriber::mock()
133 .new_span(span.clone())
134 .enter(span.clone())
135 .event(
136 expect::event()
137 .with_fields(expect::field("return").with_value(&tracing::field::debug(42)))
138 .at_level(Level::INFO),
139 )
140 .exit(span.clone())
141 .enter(span.clone())
142 .exit(span.clone())
143 .drop_span(span)
144 .only()
145 .run_with_handle();
146
147 with_default(subscriber, || block_on_future(async { ret_async().await }));
148 handle.assert_finished();
149}
150
151#[instrument(ret)]
152fn ret_impl_type() -> impl Copy {
153 42
154}
155
156#[test]
157fn test_impl_type() {
158 let span = expect::span().named("ret_impl_type");
159 let (subscriber, handle) = subscriber::mock()
160 .new_span(span.clone())
161 .enter(span.clone())
162 .event(
163 expect::event()
164 .with_fields(expect::field("return").with_value(&tracing::field::debug(42)))
165 .at_level(Level::INFO),
166 )
167 .exit(span.clone())
168 .drop_span(span)
169 .only()
170 .run_with_handle();
171
172 with_default(subscriber, ret_impl_type);
173 handle.assert_finished();
174}
175
176#[instrument(ret(Display))]
177fn ret_display() -> i32 {
178 42
179}
180
181#[test]
182fn test_dbg() {
183 let span = expect::span().named("ret_display");
184 let (subscriber, handle) = subscriber::mock()
185 .new_span(span.clone())
186 .enter(span.clone())
187 .event(
188 expect::event()
189 .with_fields(expect::field("return").with_value(&tracing::field::display(42)))
190 .at_level(Level::INFO),
191 )
192 .exit(span.clone())
193 .drop_span(span)
194 .only()
195 .run_with_handle();
196
197 with_default(subscriber, ret_display);
198 handle.assert_finished();
199}
200
201#[instrument(err, ret)]
202fn ret_and_err() -> Result<u8, TryFromIntError> {
203 u8::try_from(1234)
204}
205
206#[test]
207fn test_ret_and_err() {
208 let span = expect::span().named("ret_and_err");
209 let (subscriber, handle) = subscriber::mock()
210 .new_span(span.clone())
211 .enter(span.clone())
212 .event(
213 expect::event()
214 .with_fields(
215 expect::field("error")
216 .with_value(&tracing::field::display(u8::try_from(1234).unwrap_err()))
217 .only(),
218 )
219 .at_level(Level::ERROR),
220 )
221 .exit(span.clone())
222 .drop_span(span)
223 .only()
224 .run_with_handle();
225
226 with_default(subscriber, || ret_and_err().ok());
227 handle.assert_finished();
228}
229
230#[instrument(err, ret)]
231fn ret_and_ok() -> Result<u8, TryFromIntError> {
232 u8::try_from(123)
233}
234
235#[test]
236fn test_ret_and_ok() {
237 let span = expect::span().named("ret_and_ok");
238 let (subscriber, handle) = subscriber::mock()
239 .new_span(span.clone())
240 .enter(span.clone())
241 .event(
242 expect::event()
243 .with_fields(
244 expect::field("return")
245 .with_value(&tracing::field::debug(u8::try_from(123).unwrap()))
246 .only(),
247 )
248 .at_level(Level::INFO),
249 )
250 .exit(span.clone())
251 .drop_span(span)
252 .only()
253 .run_with_handle();
254
255 with_default(subscriber, || ret_and_ok().ok());
256 handle.assert_finished();
257}
258
259#[instrument(level = "warn", ret(level = "info"))]
260fn ret_warn_info() -> i32 {
261 42
262}
263
264#[test]
265fn test_warn_info() {
266 let span = expect::span().named("ret_warn_info").at_level(Level::WARN);
267 let (subscriber, handle) = subscriber::mock()
268 .new_span(span.clone())
269 .enter(span.clone())
270 .event(
271 expect::event()
272 .with_fields(expect::field("return").with_value(&tracing::field::debug(42)))
273 .at_level(Level::INFO),
274 )
275 .exit(span.clone())
276 .drop_span(span)
277 .only()
278 .run_with_handle();
279
280 with_default(subscriber, ret_warn_info);
281 handle.assert_finished();
282}
283
284#[instrument(ret(level = "warn", Debug))]
285fn ret_dbg_warn() -> i32 {
286 42
287}
288
289#[test]
290fn test_dbg_warn() {
291 let span = expect::span().named("ret_dbg_warn").at_level(Level::INFO);
292 let (subscriber, handle) = subscriber::mock()
293 .new_span(span.clone())
294 .enter(span.clone())
295 .event(
296 expect::event()
297 .with_fields(expect::field("return").with_value(&tracing::field::debug(42)))
298 .at_level(Level::WARN),
299 )
300 .exit(span.clone())
301 .drop_span(span)
302 .only()
303 .run_with_handle();
304
305 with_default(subscriber, ret_dbg_warn);
306 handle.assert_finished();
307}
308