1 // These tests require the thread-local scoped dispatcher, which only works when
2 // we have a standard library. The behaviour being tested should be the same
3 // with the standard lib disabled.
4 //
5 // The alternative would be for each of these tests to be defined in a separate
6 // file, which is :(
7 #![cfg(feature = "std")]
8 
9 #[macro_use]
10 extern crate tracing;
11 mod support;
12 
13 use self::support::*;
14 
15 use tracing::{
16     field::{debug, display},
17     subscriber::with_default,
18     Level,
19 };
20 
21 macro_rules! event_without_message {
22     ($name:ident: $e:expr) => {
23         #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
24         #[test]
25         fn $name() {
26             let (subscriber, handle) = subscriber::mock()
27                 .event(
28                     event::mock().with_fields(
29                         field::mock("answer")
30                             .with_value(&42)
31                             .and(
32                                 field::mock("to_question")
33                                     .with_value(&"life, the universe, and everything"),
34                             )
35                             .only(),
36                     ),
37                 )
38                 .done()
39                 .run_with_handle();
40 
41             with_default(subscriber, || {
42                 info!(
43                     answer = $e,
44                     to_question = "life, the universe, and everything"
45                 );
46             });
47 
48             handle.assert_finished();
49         }
50     };
51 }
52 
53 event_without_message! {event_without_message: 42}
54 event_without_message! {wrapping_event_without_message: std::num::Wrapping(42)}
55 event_without_message! {nonzeroi32_event_without_message: std::num::NonZeroI32::new(42).unwrap()}
56 // needs API breakage
57 //event_without_message!{nonzerou128_event_without_message: std::num::NonZeroU128::new(42).unwrap()}
58 
59 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
60 #[test]
event_with_message()61 fn event_with_message() {
62     let (subscriber, handle) = subscriber::mock()
63         .event(event::msg(format_args!(
64             "hello from my event! yak shaved = {:?}",
65             true
66         )))
67         .done()
68         .run_with_handle();
69 
70     with_default(subscriber, || {
71         debug!("hello from my event! yak shaved = {:?}", true);
72     });
73 
74     handle.assert_finished();
75 }
76 
77 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
78 #[test]
message_without_delims()79 fn message_without_delims() {
80     let (subscriber, handle) = subscriber::mock()
81         .event(
82             event::mock().with_fields(
83                 field::mock("answer")
84                     .with_value(&42)
85                     .and(field::mock("question").with_value(&"life, the universe, and everything"))
86                     .and(field::msg(format_args!(
87                         "hello from my event! tricky? {:?}!",
88                         true
89                     )))
90                     .only(),
91             ),
92         )
93         .done()
94         .run_with_handle();
95 
96     with_default(subscriber, || {
97         let question = "life, the universe, and everything";
98         debug!(answer = 42, question, "hello from {where}! tricky? {:?}!", true, where = "my event");
99     });
100 
101     handle.assert_finished();
102 }
103 
104 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
105 #[test]
string_message_without_delims()106 fn string_message_without_delims() {
107     let (subscriber, handle) = subscriber::mock()
108         .event(
109             event::mock().with_fields(
110                 field::mock("answer")
111                     .with_value(&42)
112                     .and(field::mock("question").with_value(&"life, the universe, and everything"))
113                     .and(field::msg(format_args!("hello from my event")))
114                     .only(),
115             ),
116         )
117         .done()
118         .run_with_handle();
119 
120     with_default(subscriber, || {
121         let question = "life, the universe, and everything";
122         debug!(answer = 42, question, "hello from my event");
123     });
124 
125     handle.assert_finished();
126 }
127 
128 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
129 #[test]
one_with_everything()130 fn one_with_everything() {
131     let (subscriber, handle) = subscriber::mock()
132         .event(
133             event::mock()
134                 .with_fields(
135                     field::mock("message")
136                         .with_value(&tracing::field::debug(format_args!(
137                             "{:#x} make me one with{what:.>20}",
138                             4_277_009_102u64,
139                             what = "everything"
140                         )))
141                         .and(field::mock("foo").with_value(&666))
142                         .and(field::mock("bar").with_value(&false))
143                         .and(field::mock("like_a_butterfly").with_value(&42.0))
144                         .only(),
145                 )
146                 .at_level(Level::ERROR)
147                 .with_target("whatever"),
148         )
149         .done()
150         .run_with_handle();
151 
152     with_default(subscriber, || {
153         event!(
154             target: "whatever",
155             Level::ERROR,
156             { foo = 666, bar = false, like_a_butterfly = 42.0 },
157              "{:#x} make me one with{what:.>20}", 4_277_009_102u64, what = "everything"
158         );
159     });
160 
161     handle.assert_finished();
162 }
163 
164 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
165 #[test]
moved_field()166 fn moved_field() {
167     let (subscriber, handle) = subscriber::mock()
168         .event(
169             event::mock().with_fields(
170                 field::mock("foo")
171                     .with_value(&display("hello from my event"))
172                     .only(),
173             ),
174         )
175         .done()
176         .run_with_handle();
177     with_default(subscriber, || {
178         let from = "my event";
179         event!(Level::INFO, foo = display(format!("hello from {}", from)))
180     });
181 
182     handle.assert_finished();
183 }
184 
185 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
186 #[test]
dotted_field_name()187 fn dotted_field_name() {
188     let (subscriber, handle) = subscriber::mock()
189         .event(
190             event::mock().with_fields(
191                 field::mock("foo.bar")
192                     .with_value(&true)
193                     .and(field::mock("foo.baz").with_value(&false))
194                     .only(),
195             ),
196         )
197         .done()
198         .run_with_handle();
199     with_default(subscriber, || {
200         event!(Level::INFO, foo.bar = true, foo.baz = false);
201     });
202 
203     handle.assert_finished();
204 }
205 
206 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
207 #[test]
borrowed_field()208 fn borrowed_field() {
209     let (subscriber, handle) = subscriber::mock()
210         .event(
211             event::mock().with_fields(
212                 field::mock("foo")
213                     .with_value(&display("hello from my event"))
214                     .only(),
215             ),
216         )
217         .done()
218         .run_with_handle();
219     with_default(subscriber, || {
220         let from = "my event";
221         let mut message = format!("hello from {}", from);
222         event!(Level::INFO, foo = display(&message));
223         message.push_str(", which happened!");
224     });
225 
226     handle.assert_finished();
227 }
228 
229 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
230 #[test]
231 // If emitting log instrumentation, this gets moved anyway, breaking the test.
232 #[cfg(not(feature = "log"))]
move_field_out_of_struct()233 fn move_field_out_of_struct() {
234     use tracing::field::debug;
235 
236     #[derive(Debug)]
237     struct Position {
238         x: f32,
239         y: f32,
240     }
241 
242     let pos = Position {
243         x: 3.234,
244         y: -1.223,
245     };
246     let (subscriber, handle) = subscriber::mock()
247         .event(
248             event::mock().with_fields(
249                 field::mock("x")
250                     .with_value(&debug(3.234))
251                     .and(field::mock("y").with_value(&debug(-1.223)))
252                     .only(),
253             ),
254         )
255         .event(event::mock().with_fields(field::mock("position").with_value(&debug(&pos))))
256         .done()
257         .run_with_handle();
258 
259     with_default(subscriber, || {
260         let pos = Position {
261             x: 3.234,
262             y: -1.223,
263         };
264         debug!(x = debug(pos.x), y = debug(pos.y));
265         debug!(target: "app_events", { position = debug(pos) }, "New position");
266     });
267     handle.assert_finished();
268 }
269 
270 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
271 #[test]
display_shorthand()272 fn display_shorthand() {
273     let (subscriber, handle) = subscriber::mock()
274         .event(
275             event::mock().with_fields(
276                 field::mock("my_field")
277                     .with_value(&display("hello world"))
278                     .only(),
279             ),
280         )
281         .done()
282         .run_with_handle();
283     with_default(subscriber, || {
284         event!(Level::TRACE, my_field = %"hello world");
285     });
286 
287     handle.assert_finished();
288 }
289 
290 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
291 #[test]
debug_shorthand()292 fn debug_shorthand() {
293     let (subscriber, handle) = subscriber::mock()
294         .event(
295             event::mock().with_fields(
296                 field::mock("my_field")
297                     .with_value(&debug("hello world"))
298                     .only(),
299             ),
300         )
301         .done()
302         .run_with_handle();
303     with_default(subscriber, || {
304         event!(Level::TRACE, my_field = ?"hello world");
305     });
306 
307     handle.assert_finished();
308 }
309 
310 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
311 #[test]
both_shorthands()312 fn both_shorthands() {
313     let (subscriber, handle) = subscriber::mock()
314         .event(
315             event::mock().with_fields(
316                 field::mock("display_field")
317                     .with_value(&display("hello world"))
318                     .and(field::mock("debug_field").with_value(&debug("hello world")))
319                     .only(),
320             ),
321         )
322         .done()
323         .run_with_handle();
324     with_default(subscriber, || {
325         event!(Level::TRACE, display_field = %"hello world", debug_field = ?"hello world");
326     });
327 
328     handle.assert_finished();
329 }
330 
331 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
332 #[test]
explicit_child()333 fn explicit_child() {
334     let (subscriber, handle) = subscriber::mock()
335         .new_span(span::mock().named("foo"))
336         .event(event::mock().with_explicit_parent(Some("foo")))
337         .done()
338         .run_with_handle();
339 
340     with_default(subscriber, || {
341         let foo = span!(Level::TRACE, "foo");
342         event!(parent: foo.id(), Level::TRACE, "bar");
343     });
344 
345     handle.assert_finished();
346 }
347 
348 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
349 #[test]
explicit_child_at_levels()350 fn explicit_child_at_levels() {
351     let (subscriber, handle) = subscriber::mock()
352         .new_span(span::mock().named("foo"))
353         .event(event::mock().with_explicit_parent(Some("foo")))
354         .event(event::mock().with_explicit_parent(Some("foo")))
355         .event(event::mock().with_explicit_parent(Some("foo")))
356         .event(event::mock().with_explicit_parent(Some("foo")))
357         .event(event::mock().with_explicit_parent(Some("foo")))
358         .done()
359         .run_with_handle();
360 
361     with_default(subscriber, || {
362         let foo = span!(Level::TRACE, "foo");
363         trace!(parent: foo.id(), "a");
364         debug!(parent: foo.id(), "b");
365         info!(parent: foo.id(), "c");
366         warn!(parent: foo.id(), "d");
367         error!(parent: foo.id(), "e");
368     });
369 
370     handle.assert_finished();
371 }
372 
373 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
374 #[test]
option_values()375 fn option_values() {
376     let (subscriber, handle) = subscriber::mock()
377         .event(
378             event::mock().with_fields(
379                 field::mock("some_str")
380                     .with_value(&"yes")
381                     .and(field::mock("some_bool").with_value(&true))
382                     .and(field::mock("some_u64").with_value(&42_u64))
383                     .only(),
384             ),
385         )
386         .done()
387         .run_with_handle();
388 
389     with_default(subscriber, || {
390         let some_str = Some("yes");
391         let none_str: Option<&'static str> = None;
392         let some_bool = Some(true);
393         let none_bool: Option<bool> = None;
394         let some_u64 = Some(42_u64);
395         let none_u64: Option<u64> = None;
396         trace!(
397             some_str = some_str,
398             none_str = none_str,
399             some_bool = some_bool,
400             none_bool = none_bool,
401             some_u64 = some_u64,
402             none_u64 = none_u64
403         );
404     });
405 
406     handle.assert_finished();
407 }
408 
409 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
410 #[test]
option_ref_values()411 fn option_ref_values() {
412     let (subscriber, handle) = subscriber::mock()
413         .event(
414             event::mock().with_fields(
415                 field::mock("some_str")
416                     .with_value(&"yes")
417                     .and(field::mock("some_bool").with_value(&true))
418                     .and(field::mock("some_u64").with_value(&42_u64))
419                     .only(),
420             ),
421         )
422         .done()
423         .run_with_handle();
424 
425     with_default(subscriber, || {
426         let some_str = &Some("yes");
427         let none_str: &Option<&'static str> = &None;
428         let some_bool = &Some(true);
429         let none_bool: &Option<bool> = &None;
430         let some_u64 = &Some(42_u64);
431         let none_u64: &Option<u64> = &None;
432         trace!(
433             some_str = some_str,
434             none_str = none_str,
435             some_bool = some_bool,
436             none_bool = none_bool,
437             some_u64 = some_u64,
438             none_u64 = none_u64
439         );
440     });
441 
442     handle.assert_finished();
443 }
444 
445 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
446 #[test]
option_ref_mut_values()447 fn option_ref_mut_values() {
448     let (subscriber, handle) = subscriber::mock()
449         .event(
450             event::mock().with_fields(
451                 field::mock("some_str")
452                     .with_value(&"yes")
453                     .and(field::mock("some_bool").with_value(&true))
454                     .and(field::mock("some_u64").with_value(&42_u64))
455                     .only(),
456             ),
457         )
458         .done()
459         .run_with_handle();
460 
461     with_default(subscriber, || {
462         let some_str = &mut Some("yes");
463         let none_str: &mut Option<&'static str> = &mut None;
464         let some_bool = &mut Some(true);
465         let none_bool: &mut Option<bool> = &mut None;
466         let some_u64 = &mut Some(42_u64);
467         let none_u64: &mut Option<u64> = &mut None;
468         trace!(
469             some_str = some_str,
470             none_str = none_str,
471             some_bool = some_bool,
472             none_bool = none_bool,
473             some_u64 = some_u64,
474             none_u64 = none_u64
475         );
476     });
477 
478     handle.assert_finished();
479 }
480