1 use tracing::subscriber::with_default;
2 use tracing_attributes::instrument;
3 use tracing_mock::{expect, span::NewSpan, subscriber};
4 
5 #[instrument(fields(foo = "bar", dsa = true, num = 1))]
fn_no_param()6 fn fn_no_param() {}
7 
8 #[instrument(fields(foo = "bar"))]
fn_param(param: u32)9 fn fn_param(param: u32) {}
10 
11 #[instrument(fields(foo = "bar", empty))]
fn_empty_field()12 fn fn_empty_field() {}
13 
14 #[instrument(fields(len = s.len()))]
fn_expr_field(s: &str)15 fn fn_expr_field(s: &str) {}
16 
17 #[instrument(fields(s.len = s.len(), s.is_empty = s.is_empty()))]
fn_two_expr_fields(s: &str)18 fn fn_two_expr_fields(s: &str) {
19     let _ = s;
20 }
21 
22 #[instrument(fields(%s, s.len = s.len()))]
fn_clashy_expr_field(s: &str)23 fn fn_clashy_expr_field(s: &str) {
24     let _ = s;
25 }
26 
27 #[instrument(fields(s = "s"))]
fn_clashy_expr_field2(s: &str)28 fn fn_clashy_expr_field2(s: &str) {
29     let _ = s;
30 }
31 
32 #[instrument(fields(s = &s))]
fn_string(s: String)33 fn fn_string(s: String) {
34     let _ = s;
35 }
36 
37 #[derive(Debug)]
38 struct HasField {
39     my_field: &'static str,
40 }
41 
42 impl HasField {
43     #[instrument(fields(my_field = self.my_field), skip(self))]
self_expr_field(&self)44     fn self_expr_field(&self) {}
45 }
46 
47 #[test]
fields()48 fn fields() {
49     let span = expect::span().with_field(
50         expect::field("foo")
51             .with_value(&"bar")
52             .and(expect::field("dsa").with_value(&true))
53             .and(expect::field("num").with_value(&1))
54             .only(),
55     );
56     run_test(span, || {
57         fn_no_param();
58     });
59 }
60 
61 #[test]
expr_field()62 fn expr_field() {
63     let span = expect::span().with_field(
64         expect::field("s")
65             .with_value(&"hello world")
66             .and(expect::field("len").with_value(&"hello world".len()))
67             .only(),
68     );
69     run_test(span, || {
70         fn_expr_field("hello world");
71     });
72 }
73 
74 #[test]
two_expr_fields()75 fn two_expr_fields() {
76     let span = expect::span().with_field(
77         expect::field("s")
78             .with_value(&"hello world")
79             .and(expect::field("s.len").with_value(&"hello world".len()))
80             .and(expect::field("s.is_empty").with_value(&false))
81             .only(),
82     );
83     run_test(span, || {
84         fn_two_expr_fields("hello world");
85     });
86 }
87 
88 #[test]
clashy_expr_field()89 fn clashy_expr_field() {
90     let span = expect::span().with_field(
91         // Overriding the `s` field should record `s` as a `Display` value,
92         // rather than as a `Debug` value.
93         expect::field("s")
94             .with_value(&tracing::field::display("hello world"))
95             .and(expect::field("s.len").with_value(&"hello world".len()))
96             .only(),
97     );
98     run_test(span, || {
99         fn_clashy_expr_field("hello world");
100     });
101 
102     let span = expect::span().with_field(expect::field("s").with_value(&"s").only());
103     run_test(span, || {
104         fn_clashy_expr_field2("hello world");
105     });
106 }
107 
108 #[test]
self_expr_field()109 fn self_expr_field() {
110     let span =
111         expect::span().with_field(expect::field("my_field").with_value(&"hello world").only());
112     run_test(span, || {
113         let has_field = HasField {
114             my_field: "hello world",
115         };
116         has_field.self_expr_field();
117     });
118 }
119 
120 #[test]
parameters_with_fields()121 fn parameters_with_fields() {
122     let span = expect::span().with_field(
123         expect::field("foo")
124             .with_value(&"bar")
125             .and(expect::field("param").with_value(&1u32))
126             .only(),
127     );
128     run_test(span, || {
129         fn_param(1);
130     });
131 }
132 
133 #[test]
empty_field()134 fn empty_field() {
135     let span = expect::span().with_field(expect::field("foo").with_value(&"bar").only());
136     run_test(span, || {
137         fn_empty_field();
138     });
139 }
140 
141 #[test]
string_field()142 fn string_field() {
143     let span = expect::span().with_field(expect::field("s").with_value(&"hello world").only());
144     run_test(span, || {
145         fn_string(String::from("hello world"));
146     });
147 }
148 
run_test<F: FnOnce() -> T, T>(span: NewSpan, fun: F)149 fn run_test<F: FnOnce() -> T, T>(span: NewSpan, fun: F) {
150     let (subscriber, handle) = subscriber::mock()
151         .new_span(span)
152         .enter(expect::span())
153         .exit(expect::span())
154         .only()
155         .run_with_handle();
156 
157     with_default(subscriber, fun);
158     handle.assert_finished();
159 }
160