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