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 use std::thread;
7 
8 use tracing::{
9     field::{debug, display},
10     subscriber::with_default,
11     Level, Span,
12 };
13 use tracing_mock::*;
14 
15 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
16 #[test]
handles_to_the_same_span_are_equal()17 fn 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]
handles_to_different_spans_are_not_equal()37 fn 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]
handles_to_different_spans_with_the_same_metadata_are_not_equal()50 fn 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]
spans_always_go_to_the_subscriber_that_tagged_them()68 fn 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]
spans_always_go_to_the_subscriber_that_tagged_them_even_across_threads()95 fn 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]
dropping_a_span_calls_drop_span()123 fn 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]
span_closes_after_event()141 fn 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]
new_span_after_event()160 fn 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]
event_outside_of_span()183 fn 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]
cloning_a_span_calls_clone_span()201 fn 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]
drop_span_when_exiting_dispatchers_context()217 fn 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]
clone_and_drop_span_always_go_to_the_subscriber_that_tagged_the_span()234 fn 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]
span_closes_when_exited()265 fn 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]
enter()285 fn 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]
entered()304 fn 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]
entered_api()322 fn 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]
moved_field()342 fn 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]
dotted_field_name()371 fn 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]
borrowed_field()389 fn 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"))]
move_field_out_of_struct()420 fn 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]
float_values()465 fn 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]
490 fn 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]
519 fn 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]
record_new_value_for_field()549 fn 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]
record_new_values_for_fields()580 fn 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]
new_span_with_target_and_log_level()616 fn 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]
explicit_root_span_is_root()636 fn 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]
explicit_root_span_is_root_regardless_of_ctx()651 fn 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]
explicit_child()671 fn 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]
explicit_child_at_levels()692 fn 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]
explicit_child_regardless_of_ctx()717 fn 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]
contextual_root()742 fn 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]
contextual_child()757 fn 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]
display_shorthand()781 fn 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]
debug_shorthand()801 fn 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]
both_shorthands()821 fn 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]
constant_field_name()842 fn 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