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