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#![cfg(feature = "std")]
5
6use std::thread;
7
8use tracing::{
9 field::{debug, display},
10 subscriber::with_default,
11 Level, Span,
12};
13use tracing_mock::*;
14
15#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
16#[test]
17fn handles_to_the_same_span_are_equal() {
18 // Create a mock subscriber that will return `true` on calls to
19 // `Subscriber::enabled`, so that the spans will be constructed. We
20 // won't enter any spans in this test, so the subscriber won't actually
21 // expect to see any spans.
22 with_default(subscriber::mock().run(), || {
23 let foo1 = tracing::span!(Level::TRACE, "foo");
24
25 // The purpose of this test is to assert that two clones of the same
26 // span are equal, so the clone here is kind of the whole point :)
27 #[allow(clippy::redundant_clone)]
28 let foo2 = foo1.clone();
29
30 // Two handles that point to the same span are equal.
31 assert_eq!(foo1, foo2);
32 });
33}
34
35#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
36#[test]
37fn handles_to_different_spans_are_not_equal() {
38 with_default(subscriber::mock().run(), || {
39 // Even though these spans have the same name and fields, they will have
40 // differing metadata, since they were created on different lines.
41 let foo1 = tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false);
42 let foo2 = tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false);
43
44 assert_ne!(foo1, foo2);
45 });
46}
47
48#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
49#[test]
50fn handles_to_different_spans_with_the_same_metadata_are_not_equal() {
51 // Every time time this function is called, it will return a _new
52 // instance_ of a span with the same metadata, name, and fields.
53 fn make_span() -> Span {
54 tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false)
55 }
56
57 with_default(subscriber::mock().run(), || {
58 let foo1 = make_span();
59 let foo2 = make_span();
60
61 assert_ne!(foo1, foo2);
62 // assert_ne!(foo1.data(), foo2.data());
63 });
64}
65
66#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
67#[test]
68fn spans_always_go_to_the_subscriber_that_tagged_them() {
69 let subscriber1 = subscriber::mock()
70 .enter(expect::span().named("foo"))
71 .exit(expect::span().named("foo"))
72 .enter(expect::span().named("foo"))
73 .exit(expect::span().named("foo"))
74 .drop_span(expect::span().named("foo"))
75 .only()
76 .run();
77 let subscriber2 = subscriber::mock().run();
78
79 let foo = with_default(subscriber1, || {
80 let foo = tracing::span!(Level::TRACE, "foo");
81 foo.in_scope(|| {});
82 foo
83 });
84 // Even though we enter subscriber 2's context, the subscriber that
85 // tagged the span should see the enter/exit.
86 with_default(subscriber2, move || foo.in_scope(|| {}));
87}
88
89// This gets exempt from testing in wasm because of: `thread::spawn` which is
90// not yet possible to do in WASM. There is work going on see:
91// <https://rustwasm.github.io/2018/10/24/multithreading-rust-and-wasm.html>
92//
93// But for now since it's not possible we don't need to test for it :)
94#[test]
95fn spans_always_go_to_the_subscriber_that_tagged_them_even_across_threads() {
96 let subscriber1 = subscriber::mock()
97 .enter(expect::span().named("foo"))
98 .exit(expect::span().named("foo"))
99 .enter(expect::span().named("foo"))
100 .exit(expect::span().named("foo"))
101 .drop_span(expect::span().named("foo"))
102 .only()
103 .run();
104 let foo = with_default(subscriber1, || {
105 let foo = tracing::span!(Level::TRACE, "foo");
106 foo.in_scope(|| {});
107 foo
108 });
109
110 // Even though we enter subscriber 2's context, the subscriber that
111 // tagged the span should see the enter/exit.
112 thread::spawn(move || {
113 with_default(subscriber::mock().run(), || {
114 foo.in_scope(|| {});
115 })
116 })
117 .join()
118 .unwrap();
119}
120
121#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
122#[test]
123fn dropping_a_span_calls_drop_span() {
124 let (subscriber, handle) = subscriber::mock()
125 .enter(expect::span().named("foo"))
126 .exit(expect::span().named("foo"))
127 .drop_span(expect::span().named("foo"))
128 .only()
129 .run_with_handle();
130 with_default(subscriber, || {
131 let span = tracing::span!(Level::TRACE, "foo");
132 span.in_scope(|| {});
133 drop(span);
134 });
135
136 handle.assert_finished();
137}
138
139#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
140#[test]
141fn span_closes_after_event() {
142 let (subscriber, handle) = subscriber::mock()
143 .enter(expect::span().named("foo"))
144 .event(expect::event())
145 .exit(expect::span().named("foo"))
146 .drop_span(expect::span().named("foo"))
147 .only()
148 .run_with_handle();
149 with_default(subscriber, || {
150 tracing::span!(Level::TRACE, "foo").in_scope(|| {
151 tracing::event!(Level::DEBUG, {}, "my tracing::event!");
152 });
153 });
154
155 handle.assert_finished();
156}
157
158#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
159#[test]
160fn new_span_after_event() {
161 let (subscriber, handle) = subscriber::mock()
162 .enter(expect::span().named("foo"))
163 .event(expect::event())
164 .exit(expect::span().named("foo"))
165 .drop_span(expect::span().named("foo"))
166 .enter(expect::span().named("bar"))
167 .exit(expect::span().named("bar"))
168 .drop_span(expect::span().named("bar"))
169 .only()
170 .run_with_handle();
171 with_default(subscriber, || {
172 tracing::span!(Level::TRACE, "foo").in_scope(|| {
173 tracing::event!(Level::DEBUG, {}, "my tracing::event!");
174 });
175 tracing::span!(Level::TRACE, "bar").in_scope(|| {});
176 });
177
178 handle.assert_finished();
179}
180
181#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
182#[test]
183fn event_outside_of_span() {
184 let (subscriber, handle) = subscriber::mock()
185 .event(expect::event())
186 .enter(expect::span().named("foo"))
187 .exit(expect::span().named("foo"))
188 .drop_span(expect::span().named("foo"))
189 .only()
190 .run_with_handle();
191 with_default(subscriber, || {
192 tracing::debug!("my tracing::event!");
193 tracing::span!(Level::TRACE, "foo").in_scope(|| {});
194 });
195
196 handle.assert_finished();
197}
198
199#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
200#[test]
201fn cloning_a_span_calls_clone_span() {
202 let (subscriber, handle) = subscriber::mock()
203 .clone_span(expect::span().named("foo"))
204 .run_with_handle();
205 with_default(subscriber, || {
206 let span = tracing::span!(Level::TRACE, "foo");
207 // Allow the "redundant" `.clone` since it is used to call into the `.clone_span` hook.
208 #[allow(clippy::redundant_clone)]
209 let _span2 = span.clone();
210 });
211
212 handle.assert_finished();
213}
214
215#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
216#[test]
217fn drop_span_when_exiting_dispatchers_context() {
218 let (subscriber, handle) = subscriber::mock()
219 .clone_span(expect::span().named("foo"))
220 .drop_span(expect::span().named("foo"))
221 .drop_span(expect::span().named("foo"))
222 .run_with_handle();
223 with_default(subscriber, || {
224 let span = tracing::span!(Level::TRACE, "foo");
225 let _span2 = span.clone();
226 drop(span);
227 });
228
229 handle.assert_finished();
230}
231
232#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
233#[test]
234fn clone_and_drop_span_always_go_to_the_subscriber_that_tagged_the_span() {
235 let (subscriber1, handle1) = subscriber::mock()
236 .enter(expect::span().named("foo"))
237 .exit(expect::span().named("foo"))
238 .clone_span(expect::span().named("foo"))
239 .enter(expect::span().named("foo"))
240 .exit(expect::span().named("foo"))
241 .drop_span(expect::span().named("foo"))
242 .drop_span(expect::span().named("foo"))
243 .run_with_handle();
244 let subscriber2 = subscriber::mock().only().run();
245
246 let foo = with_default(subscriber1, || {
247 let foo = tracing::span!(Level::TRACE, "foo");
248 foo.in_scope(|| {});
249 foo
250 });
251 // Even though we enter subscriber 2's context, the subscriber that
252 // tagged the span should see the enter/exit.
253 with_default(subscriber2, move || {
254 let foo2 = foo.clone();
255 foo.in_scope(|| {});
256 drop(foo);
257 drop(foo2);
258 });
259
260 handle1.assert_finished();
261}
262
263#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
264#[test]
265fn span_closes_when_exited() {
266 let (subscriber, handle) = subscriber::mock()
267 .enter(expect::span().named("foo"))
268 .exit(expect::span().named("foo"))
269 .drop_span(expect::span().named("foo"))
270 .only()
271 .run_with_handle();
272 with_default(subscriber, || {
273 let foo = tracing::span!(Level::TRACE, "foo");
274
275 foo.in_scope(|| {});
276
277 drop(foo);
278 });
279
280 handle.assert_finished();
281}
282
283#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
284#[test]
285fn enter() {
286 let (subscriber, handle) = subscriber::mock()
287 .enter(expect::span().named("foo"))
288 .event(expect::event())
289 .exit(expect::span().named("foo"))
290 .drop_span(expect::span().named("foo"))
291 .only()
292 .run_with_handle();
293 with_default(subscriber, || {
294 let foo = tracing::span!(Level::TRACE, "foo");
295 let _enter = foo.enter();
296 tracing::debug!("dropping guard...");
297 });
298
299 handle.assert_finished();
300}
301
302#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
303#[test]
304fn entered() {
305 let (subscriber, handle) = subscriber::mock()
306 .enter(expect::span().named("foo"))
307 .event(expect::event())
308 .exit(expect::span().named("foo"))
309 .drop_span(expect::span().named("foo"))
310 .only()
311 .run_with_handle();
312 with_default(subscriber, || {
313 let _span = tracing::span!(Level::TRACE, "foo").entered();
314 tracing::debug!("dropping guard...");
315 });
316
317 handle.assert_finished();
318}
319
320#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
321#[test]
322fn entered_api() {
323 let (subscriber, handle) = subscriber::mock()
324 .enter(expect::span().named("foo"))
325 .event(expect::event())
326 .exit(expect::span().named("foo"))
327 .drop_span(expect::span().named("foo"))
328 .only()
329 .run_with_handle();
330 with_default(subscriber, || {
331 let span = tracing::span!(Level::TRACE, "foo").entered();
332 let _derefs_to_span = span.id();
333 tracing::debug!("exiting span...");
334 let _: Span = span.exit();
335 });
336
337 handle.assert_finished();
338}
339
340#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
341#[test]
342fn moved_field() {
343 let (subscriber, handle) = subscriber::mock()
344 .new_span(
345 expect::span().named("foo").with_field(
346 expect::field("bar")
347 .with_value(&display("hello from my span"))
348 .only(),
349 ),
350 )
351 .enter(expect::span().named("foo"))
352 .exit(expect::span().named("foo"))
353 .drop_span(expect::span().named("foo"))
354 .only()
355 .run_with_handle();
356 with_default(subscriber, || {
357 let from = "my span";
358 let span = tracing::span!(
359 Level::TRACE,
360 "foo",
361 bar = display(format!("hello from {}", from))
362 );
363 span.in_scope(|| {});
364 });
365
366 handle.assert_finished();
367}
368
369#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
370#[test]
371fn dotted_field_name() {
372 let (subscriber, handle) = subscriber::mock()
373 .new_span(
374 expect::span()
375 .named("foo")
376 .with_field(expect::field("fields.bar").with_value(&true).only()),
377 )
378 .only()
379 .run_with_handle();
380 with_default(subscriber, || {
381 tracing::span!(Level::TRACE, "foo", fields.bar = true);
382 });
383
384 handle.assert_finished();
385}
386
387#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
388#[test]
389fn borrowed_field() {
390 let (subscriber, handle) = subscriber::mock()
391 .new_span(
392 expect::span().named("foo").with_field(
393 expect::field("bar")
394 .with_value(&display("hello from my span"))
395 .only(),
396 ),
397 )
398 .enter(expect::span().named("foo"))
399 .exit(expect::span().named("foo"))
400 .drop_span(expect::span().named("foo"))
401 .only()
402 .run_with_handle();
403
404 with_default(subscriber, || {
405 let from = "my span";
406 let mut message = format!("hello from {}", from);
407 let span = tracing::span!(Level::TRACE, "foo", bar = display(&message));
408 span.in_scope(|| {
409 message.insert_str(10, " inside");
410 });
411 });
412
413 handle.assert_finished();
414}
415
416#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
417#[test]
418// If emitting log instrumentation, this gets moved anyway, breaking the test.
419#[cfg(not(feature = "log"))]
420fn move_field_out_of_struct() {
421 use tracing::field::debug;
422
423 #[derive(Debug)]
424 struct Position {
425 x: f32,
426 y: f32,
427 }
428
429 let pos = Position {
430 x: 3.234,
431 y: -1.223,
432 };
433 let (subscriber, handle) = subscriber::mock()
434 .new_span(
435 expect::span().named("foo").with_field(
436 expect::field("x")
437 .with_value(&debug(3.234))
438 .and(expect::field("y").with_value(&debug(-1.223)))
439 .only(),
440 ),
441 )
442 .new_span(
443 expect::span()
444 .named("bar")
445 .with_field(expect::field("position").with_value(&debug(&pos)).only()),
446 )
447 .run_with_handle();
448
449 with_default(subscriber, || {
450 let pos = Position {
451 x: 3.234,
452 y: -1.223,
453 };
454 let foo = tracing::span!(Level::TRACE, "foo", x = debug(pos.x), y = debug(pos.y));
455 let bar = tracing::span!(Level::TRACE, "bar", position = debug(pos));
456 foo.in_scope(|| {});
457 bar.in_scope(|| {});
458 });
459
460 handle.assert_finished();
461}
462
463#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
464#[test]
465fn float_values() {
466 let (subscriber, handle) = subscriber::mock()
467 .new_span(
468 expect::span().named("foo").with_field(
469 expect::field("x")
470 .with_value(&3.234)
471 .and(expect::field("y").with_value(&-1.223))
472 .only(),
473 ),
474 )
475 .run_with_handle();
476
477 with_default(subscriber, || {
478 let foo = tracing::span!(Level::TRACE, "foo", x = 3.234, y = -1.223);
479 foo.in_scope(|| {});
480 });
481
482 handle.assert_finished();
483}
484
485// TODO(#1138): determine a new syntax for uninitialized span fields, and
486// re-enable these.
487/*
488#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
489#[test]
490fn add_field_after_new_span() {
491 let (subscriber, handle) = subscriber::mock()
492 .new_span(
493 expect::span()
494 .named("foo")
495 .with_field(expect::field("bar").with_value(&5)
496 .and(expect::field("baz").with_value).only()),
497 )
498 .record(
499 expect::span().named("foo"),
500 field::expect("baz").with_value(&true).only(),
501 )
502 .enter(expect::span().named("foo"))
503 .exit(expect::span().named("foo"))
504 .drop_span(expect::span().named("foo"))
505 .only()
506 .run_with_handle();
507
508 with_default(subscriber, || {
509 let span = tracing::span!(Level::TRACE, "foo", bar = 5, baz = false);
510 span.record("baz", &true);
511 span.in_scope(|| {})
512 });
513
514 handle.assert_finished();
515}
516
517#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
518#[test]
519fn add_fields_only_after_new_span() {
520 let (subscriber, handle) = subscriber::mock()
521 .new_span(expect::span().named("foo"))
522 .record(
523 expect::span().named("foo"),
524 field::expect("bar").with_value(&5).only(),
525 )
526 .record(
527 expect::span().named("foo"),
528 field::expect("baz").with_value(&true).only(),
529 )
530 .enter(expect::span().named("foo"))
531 .exit(expect::span().named("foo"))
532 .drop_span(expect::span().named("foo"))
533 .only()
534 .run_with_handle();
535
536 with_default(subscriber, || {
537 let span = tracing::span!(Level::TRACE, "foo", bar = _, baz = _);
538 span.record("bar", &5);
539 span.record("baz", &true);
540 span.in_scope(|| {})
541 });
542
543 handle.assert_finished();
544}
545*/
546
547#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
548#[test]
549fn record_new_value_for_field() {
550 let (subscriber, handle) = subscriber::mock()
551 .new_span(
552 expect::span().named("foo").with_field(
553 expect::field("bar")
554 .with_value(&5)
555 .and(expect::field("baz").with_value(&false))
556 .only(),
557 ),
558 )
559 .record(
560 expect::span().named("foo"),
561 expect::field("baz").with_value(&true).only(),
562 )
563 .enter(expect::span().named("foo"))
564 .exit(expect::span().named("foo"))
565 .drop_span(expect::span().named("foo"))
566 .only()
567 .run_with_handle();
568
569 with_default(subscriber, || {
570 let span = tracing::span!(Level::TRACE, "foo", bar = 5, baz = false);
571 span.record("baz", true);
572 span.in_scope(|| {})
573 });
574
575 handle.assert_finished();
576}
577
578#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
579#[test]
580fn record_new_values_for_fields() {
581 let (subscriber, handle) = subscriber::mock()
582 .new_span(
583 expect::span().named("foo").with_field(
584 expect::field("bar")
585 .with_value(&4)
586 .and(expect::field("baz").with_value(&false))
587 .only(),
588 ),
589 )
590 .record(
591 expect::span().named("foo"),
592 expect::field("bar").with_value(&5).only(),
593 )
594 .record(
595 expect::span().named("foo"),
596 expect::field("baz").with_value(&true).only(),
597 )
598 .enter(expect::span().named("foo"))
599 .exit(expect::span().named("foo"))
600 .drop_span(expect::span().named("foo"))
601 .only()
602 .run_with_handle();
603
604 with_default(subscriber, || {
605 let span = tracing::span!(Level::TRACE, "foo", bar = 4, baz = false);
606 span.record("bar", 5);
607 span.record("baz", true);
608 span.in_scope(|| {})
609 });
610
611 handle.assert_finished();
612}
613
614#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
615#[test]
616fn new_span_with_target_and_log_level() {
617 let (subscriber, handle) = subscriber::mock()
618 .new_span(
619 expect::span()
620 .named("foo")
621 .with_target("app_span")
622 .at_level(Level::DEBUG),
623 )
624 .only()
625 .run_with_handle();
626
627 with_default(subscriber, || {
628 tracing::span!(target: "app_span", Level::DEBUG, "foo");
629 });
630
631 handle.assert_finished();
632}
633
634#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
635#[test]
636fn explicit_root_span_is_root() {
637 let (subscriber, handle) = subscriber::mock()
638 .new_span(expect::span().named("foo").with_explicit_parent(None))
639 .only()
640 .run_with_handle();
641
642 with_default(subscriber, || {
643 tracing::span!(parent: None, Level::TRACE, "foo");
644 });
645
646 handle.assert_finished();
647}
648
649#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
650#[test]
651fn explicit_root_span_is_root_regardless_of_ctx() {
652 let (subscriber, handle) = subscriber::mock()
653 .new_span(expect::span().named("foo"))
654 .enter(expect::span().named("foo"))
655 .new_span(expect::span().named("bar").with_explicit_parent(None))
656 .exit(expect::span().named("foo"))
657 .only()
658 .run_with_handle();
659
660 with_default(subscriber, || {
661 tracing::span!(Level::TRACE, "foo").in_scope(|| {
662 tracing::span!(parent: None, Level::TRACE, "bar");
663 })
664 });
665
666 handle.assert_finished();
667}
668
669#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
670#[test]
671fn explicit_child() {
672 let (subscriber, handle) = subscriber::mock()
673 .new_span(expect::span().named("foo"))
674 .new_span(
675 expect::span()
676 .named("bar")
677 .with_explicit_parent(Some("foo")),
678 )
679 .only()
680 .run_with_handle();
681
682 with_default(subscriber, || {
683 let foo = tracing::span!(Level::TRACE, "foo");
684 tracing::span!(parent: foo.id(), Level::TRACE, "bar");
685 });
686
687 handle.assert_finished();
688}
689
690#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
691#[test]
692fn explicit_child_at_levels() {
693 let (subscriber, handle) = subscriber::mock()
694 .new_span(expect::span().named("foo"))
695 .new_span(expect::span().named("a").with_explicit_parent(Some("foo")))
696 .new_span(expect::span().named("b").with_explicit_parent(Some("foo")))
697 .new_span(expect::span().named("c").with_explicit_parent(Some("foo")))
698 .new_span(expect::span().named("d").with_explicit_parent(Some("foo")))
699 .new_span(expect::span().named("e").with_explicit_parent(Some("foo")))
700 .only()
701 .run_with_handle();
702
703 with_default(subscriber, || {
704 let foo = tracing::span!(Level::TRACE, "foo");
705 tracing::trace_span!(parent: foo.id(), "a");
706 tracing::debug_span!(parent: foo.id(), "b");
707 tracing::info_span!(parent: foo.id(), "c");
708 tracing::warn_span!(parent: foo.id(), "d");
709 tracing::error_span!(parent: foo.id(), "e");
710 });
711
712 handle.assert_finished();
713}
714
715#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
716#[test]
717fn explicit_child_regardless_of_ctx() {
718 let (subscriber, handle) = subscriber::mock()
719 .new_span(expect::span().named("foo"))
720 .new_span(expect::span().named("bar"))
721 .enter(expect::span().named("bar"))
722 .new_span(
723 expect::span()
724 .named("baz")
725 .with_explicit_parent(Some("foo")),
726 )
727 .exit(expect::span().named("bar"))
728 .only()
729 .run_with_handle();
730
731 with_default(subscriber, || {
732 let foo = tracing::span!(Level::TRACE, "foo");
733 tracing::span!(Level::TRACE, "bar")
734 .in_scope(|| tracing::span!(parent: foo.id(), Level::TRACE, "baz"))
735 });
736
737 handle.assert_finished();
738}
739
740#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
741#[test]
742fn contextual_root() {
743 let (subscriber, handle) = subscriber::mock()
744 .new_span(expect::span().named("foo").with_contextual_parent(None))
745 .only()
746 .run_with_handle();
747
748 with_default(subscriber, || {
749 tracing::span!(Level::TRACE, "foo");
750 });
751
752 handle.assert_finished();
753}
754
755#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
756#[test]
757fn contextual_child() {
758 let (subscriber, handle) = subscriber::mock()
759 .new_span(expect::span().named("foo"))
760 .enter(expect::span().named("foo"))
761 .new_span(
762 expect::span()
763 .named("bar")
764 .with_contextual_parent(Some("foo")),
765 )
766 .exit(expect::span().named("foo"))
767 .only()
768 .run_with_handle();
769
770 with_default(subscriber, || {
771 tracing::span!(Level::TRACE, "foo").in_scope(|| {
772 tracing::span!(Level::TRACE, "bar");
773 })
774 });
775
776 handle.assert_finished();
777}
778
779#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
780#[test]
781fn display_shorthand() {
782 let (subscriber, handle) = subscriber::mock()
783 .new_span(
784 expect::span().named("my_span").with_field(
785 expect::field("my_field")
786 .with_value(&display("hello world"))
787 .only(),
788 ),
789 )
790 .only()
791 .run_with_handle();
792 with_default(subscriber, || {
793 tracing::span!(Level::TRACE, "my_span", my_field = %"hello world");
794 });
795
796 handle.assert_finished();
797}
798
799#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
800#[test]
801fn debug_shorthand() {
802 let (subscriber, handle) = subscriber::mock()
803 .new_span(
804 expect::span().named("my_span").with_field(
805 expect::field("my_field")
806 .with_value(&debug("hello world"))
807 .only(),
808 ),
809 )
810 .only()
811 .run_with_handle();
812 with_default(subscriber, || {
813 tracing::span!(Level::TRACE, "my_span", my_field = ?"hello world");
814 });
815
816 handle.assert_finished();
817}
818
819#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
820#[test]
821fn both_shorthands() {
822 let (subscriber, handle) = subscriber::mock()
823 .new_span(
824 expect::span().named("my_span").with_field(
825 expect::field("display_field")
826 .with_value(&display("hello world"))
827 .and(expect::field("debug_field").with_value(&debug("hello world")))
828 .only(),
829 ),
830 )
831 .only()
832 .run_with_handle();
833 with_default(subscriber, || {
834 tracing::span!(Level::TRACE, "my_span", display_field = %"hello world", debug_field = ?"hello world");
835 });
836
837 handle.assert_finished();
838}
839
840#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
841#[test]
842fn constant_field_name() {
843 let (subscriber, handle) = subscriber::mock()
844 .new_span(
845 expect::span().named("my_span").with_field(
846 expect::field("foo")
847 .with_value(&"bar")
848 .and(expect::field("constant string").with_value(&"also works"))
849 .and(expect::field("foo.bar").with_value(&"baz"))
850 .only(),
851 ),
852 )
853 .only()
854 .run_with_handle();
855
856 with_default(subscriber, || {
857 const FOO: &str = "foo";
858 tracing::span!(
859 Level::TRACE,
860 "my_span",
861 { std::convert::identity(FOO) } = "bar",
862 { "constant string" } = "also works",
863 foo.bar = "baz",
864 );
865 });
866
867 handle.assert_finished();
868}
869