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 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
462 #[test]
float_values()463 fn float_values() {
464     let (subscriber, handle) = subscriber::mock()
465         .new_span(
466             span::mock().named("foo").with_field(
467                 field::mock("x")
468                     .with_value(&3.234)
469                     .and(field::mock("y").with_value(&-1.223))
470                     .only(),
471             ),
472         )
473         .run_with_handle();
474 
475     with_default(subscriber, || {
476         let foo = span!(Level::TRACE, "foo", x = 3.234, y = -1.223);
477         foo.in_scope(|| {});
478     });
479 
480     handle.assert_finished();
481 }
482 
483 // TODO(#1138): determine a new syntax for uninitialized span fields, and
484 // re-enable these.
485 /*
486 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
487 #[test]
488 fn add_field_after_new_span() {
489     let (subscriber, handle) = subscriber::mock()
490         .new_span(
491             span::mock()
492                 .named("foo")
493                 .with_field(field::mock("bar").with_value(&5)
494                 .and(field::mock("baz").with_value).only()),
495         )
496         .record(
497             span::mock().named("foo"),
498             field::mock("baz").with_value(&true).only(),
499         )
500         .enter(span::mock().named("foo"))
501         .exit(span::mock().named("foo"))
502         .drop_span(span::mock().named("foo"))
503         .done()
504         .run_with_handle();
505 
506     with_default(subscriber, || {
507         let span = span!(Level::TRACE, "foo", bar = 5, baz = false);
508         span.record("baz", &true);
509         span.in_scope(|| {})
510     });
511 
512     handle.assert_finished();
513 }
514 
515 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
516 #[test]
517 fn add_fields_only_after_new_span() {
518     let (subscriber, handle) = subscriber::mock()
519         .new_span(span::mock().named("foo"))
520         .record(
521             span::mock().named("foo"),
522             field::mock("bar").with_value(&5).only(),
523         )
524         .record(
525             span::mock().named("foo"),
526             field::mock("baz").with_value(&true).only(),
527         )
528         .enter(span::mock().named("foo"))
529         .exit(span::mock().named("foo"))
530         .drop_span(span::mock().named("foo"))
531         .done()
532         .run_with_handle();
533 
534     with_default(subscriber, || {
535         let span = span!(Level::TRACE, "foo", bar = _, baz = _);
536         span.record("bar", &5);
537         span.record("baz", &true);
538         span.in_scope(|| {})
539     });
540 
541     handle.assert_finished();
542 }
543 */
544 
545 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
546 #[test]
record_new_value_for_field()547 fn record_new_value_for_field() {
548     let (subscriber, handle) = subscriber::mock()
549         .new_span(
550             span::mock().named("foo").with_field(
551                 field::mock("bar")
552                     .with_value(&5)
553                     .and(field::mock("baz").with_value(&false))
554                     .only(),
555             ),
556         )
557         .record(
558             span::mock().named("foo"),
559             field::mock("baz").with_value(&true).only(),
560         )
561         .enter(span::mock().named("foo"))
562         .exit(span::mock().named("foo"))
563         .drop_span(span::mock().named("foo"))
564         .done()
565         .run_with_handle();
566 
567     with_default(subscriber, || {
568         let span = span!(Level::TRACE, "foo", bar = 5, baz = false);
569         span.record("baz", &true);
570         span.in_scope(|| {})
571     });
572 
573     handle.assert_finished();
574 }
575 
576 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
577 #[test]
record_new_values_for_fields()578 fn record_new_values_for_fields() {
579     let (subscriber, handle) = subscriber::mock()
580         .new_span(
581             span::mock().named("foo").with_field(
582                 field::mock("bar")
583                     .with_value(&4)
584                     .and(field::mock("baz").with_value(&false))
585                     .only(),
586             ),
587         )
588         .record(
589             span::mock().named("foo"),
590             field::mock("bar").with_value(&5).only(),
591         )
592         .record(
593             span::mock().named("foo"),
594             field::mock("baz").with_value(&true).only(),
595         )
596         .enter(span::mock().named("foo"))
597         .exit(span::mock().named("foo"))
598         .drop_span(span::mock().named("foo"))
599         .done()
600         .run_with_handle();
601 
602     with_default(subscriber, || {
603         let span = span!(Level::TRACE, "foo", bar = 4, baz = false);
604         span.record("bar", &5);
605         span.record("baz", &true);
606         span.in_scope(|| {})
607     });
608 
609     handle.assert_finished();
610 }
611 
612 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
613 #[test]
new_span_with_target_and_log_level()614 fn new_span_with_target_and_log_level() {
615     let (subscriber, handle) = subscriber::mock()
616         .new_span(
617             span::mock()
618                 .named("foo")
619                 .with_target("app_span")
620                 .at_level(Level::DEBUG),
621         )
622         .done()
623         .run_with_handle();
624 
625     with_default(subscriber, || {
626         span!(target: "app_span", Level::DEBUG, "foo");
627     });
628 
629     handle.assert_finished();
630 }
631 
632 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
633 #[test]
explicit_root_span_is_root()634 fn explicit_root_span_is_root() {
635     let (subscriber, handle) = subscriber::mock()
636         .new_span(span::mock().named("foo").with_explicit_parent(None))
637         .done()
638         .run_with_handle();
639 
640     with_default(subscriber, || {
641         span!(parent: None, Level::TRACE, "foo");
642     });
643 
644     handle.assert_finished();
645 }
646 
647 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
648 #[test]
explicit_root_span_is_root_regardless_of_ctx()649 fn explicit_root_span_is_root_regardless_of_ctx() {
650     let (subscriber, handle) = subscriber::mock()
651         .new_span(span::mock().named("foo"))
652         .enter(span::mock().named("foo"))
653         .new_span(span::mock().named("bar").with_explicit_parent(None))
654         .exit(span::mock().named("foo"))
655         .done()
656         .run_with_handle();
657 
658     with_default(subscriber, || {
659         span!(Level::TRACE, "foo").in_scope(|| {
660             span!(parent: None, Level::TRACE, "bar");
661         })
662     });
663 
664     handle.assert_finished();
665 }
666 
667 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
668 #[test]
explicit_child()669 fn explicit_child() {
670     let (subscriber, handle) = subscriber::mock()
671         .new_span(span::mock().named("foo"))
672         .new_span(span::mock().named("bar").with_explicit_parent(Some("foo")))
673         .done()
674         .run_with_handle();
675 
676     with_default(subscriber, || {
677         let foo = span!(Level::TRACE, "foo");
678         span!(parent: foo.id(), Level::TRACE, "bar");
679     });
680 
681     handle.assert_finished();
682 }
683 
684 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
685 #[test]
explicit_child_at_levels()686 fn explicit_child_at_levels() {
687     let (subscriber, handle) = subscriber::mock()
688         .new_span(span::mock().named("foo"))
689         .new_span(span::mock().named("a").with_explicit_parent(Some("foo")))
690         .new_span(span::mock().named("b").with_explicit_parent(Some("foo")))
691         .new_span(span::mock().named("c").with_explicit_parent(Some("foo")))
692         .new_span(span::mock().named("d").with_explicit_parent(Some("foo")))
693         .new_span(span::mock().named("e").with_explicit_parent(Some("foo")))
694         .done()
695         .run_with_handle();
696 
697     with_default(subscriber, || {
698         let foo = span!(Level::TRACE, "foo");
699         trace_span!(parent: foo.id(), "a");
700         debug_span!(parent: foo.id(), "b");
701         info_span!(parent: foo.id(), "c");
702         warn_span!(parent: foo.id(), "d");
703         error_span!(parent: foo.id(), "e");
704     });
705 
706     handle.assert_finished();
707 }
708 
709 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
710 #[test]
explicit_child_regardless_of_ctx()711 fn explicit_child_regardless_of_ctx() {
712     let (subscriber, handle) = subscriber::mock()
713         .new_span(span::mock().named("foo"))
714         .new_span(span::mock().named("bar"))
715         .enter(span::mock().named("bar"))
716         .new_span(span::mock().named("baz").with_explicit_parent(Some("foo")))
717         .exit(span::mock().named("bar"))
718         .done()
719         .run_with_handle();
720 
721     with_default(subscriber, || {
722         let foo = span!(Level::TRACE, "foo");
723         span!(Level::TRACE, "bar").in_scope(|| span!(parent: foo.id(), Level::TRACE, "baz"))
724     });
725 
726     handle.assert_finished();
727 }
728 
729 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
730 #[test]
contextual_root()731 fn contextual_root() {
732     let (subscriber, handle) = subscriber::mock()
733         .new_span(span::mock().named("foo").with_contextual_parent(None))
734         .done()
735         .run_with_handle();
736 
737     with_default(subscriber, || {
738         span!(Level::TRACE, "foo");
739     });
740 
741     handle.assert_finished();
742 }
743 
744 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
745 #[test]
contextual_child()746 fn contextual_child() {
747     let (subscriber, handle) = subscriber::mock()
748         .new_span(span::mock().named("foo"))
749         .enter(span::mock().named("foo"))
750         .new_span(
751             span::mock()
752                 .named("bar")
753                 .with_contextual_parent(Some("foo")),
754         )
755         .exit(span::mock().named("foo"))
756         .done()
757         .run_with_handle();
758 
759     with_default(subscriber, || {
760         span!(Level::TRACE, "foo").in_scope(|| {
761             span!(Level::TRACE, "bar");
762         })
763     });
764 
765     handle.assert_finished();
766 }
767 
768 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
769 #[test]
display_shorthand()770 fn display_shorthand() {
771     let (subscriber, handle) = subscriber::mock()
772         .new_span(
773             span::mock().named("my_span").with_field(
774                 field::mock("my_field")
775                     .with_value(&display("hello world"))
776                     .only(),
777             ),
778         )
779         .done()
780         .run_with_handle();
781     with_default(subscriber, || {
782         span!(Level::TRACE, "my_span", my_field = %"hello world");
783     });
784 
785     handle.assert_finished();
786 }
787 
788 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
789 #[test]
debug_shorthand()790 fn debug_shorthand() {
791     let (subscriber, handle) = subscriber::mock()
792         .new_span(
793             span::mock().named("my_span").with_field(
794                 field::mock("my_field")
795                     .with_value(&debug("hello world"))
796                     .only(),
797             ),
798         )
799         .done()
800         .run_with_handle();
801     with_default(subscriber, || {
802         span!(Level::TRACE, "my_span", my_field = ?"hello world");
803     });
804 
805     handle.assert_finished();
806 }
807 
808 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
809 #[test]
both_shorthands()810 fn both_shorthands() {
811     let (subscriber, handle) = subscriber::mock()
812         .new_span(
813             span::mock().named("my_span").with_field(
814                 field::mock("display_field")
815                     .with_value(&display("hello world"))
816                     .and(field::mock("debug_field").with_value(&debug("hello world")))
817                     .only(),
818             ),
819         )
820         .done()
821         .run_with_handle();
822     with_default(subscriber, || {
823         span!(Level::TRACE, "my_span", display_field = %"hello world", debug_field = ?"hello world");
824     });
825 
826     handle.assert_finished();
827 }
828