tracing_assert_macros/
lib.rs1#![cfg_attr(test, allow(non_snake_case))]
2mod readme_doctests;
3
4#[macro_export]
20macro_rules! tracing_capture_events {
21 ( $code_under_test:block ) => {{
22 let events = {
23 use tracing_assert_core::{
24 lazy_static::lazy_static,
25 tracing_subscriber::{self, layer::SubscriberExt},
26 Event, Layer, Notification,
27 };
28
29 lazy_static! {
30 static ref LAYER: Layer<Notification> = Layer::new();
31 }
32
33 let subscriber = tracing_subscriber::FmtSubscriber::builder()
34 .with_test_writer()
35 .with_max_level(tracing::Level::TRACE)
36 .pretty()
37 .finish()
38 .with(&*LAYER);
39
40 tracing::subscriber::with_default(subscriber, || $code_under_test);
41
42 let events: Vec<Event> = LAYER.drain_events();
43 events
44 };
45 events
46 }};
47}
48
49#[macro_export]
68macro_rules! tracing_capture_event_fields {
69 ( $code_under_test:block ) => {{
70 let events = {
71 use tracing_assert_core::FieldValueMap;
72
73 let events = $crate::tracing_capture_events!({ $code_under_test });
74 let events: Vec<FieldValueMap> =
75 events.into_iter().map(|e| e.fields().clone()).collect();
76 events
77 };
78 events
79 }};
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use tracing_assert_core::{debug_fmt_ext::DebugFmtExt, FieldValueMap};
86
87 #[derive(Debug)]
88 pub enum MyDomainLogEvent {
89 Foo,
90 Bar,
91 }
92
93 #[test]
94 fn tracing_capture_event_fields__captures_multiple_custom_structs_per_event() {
95 fn emit_2_complex_payload_events() {
97 tracing::info_span!("outermost span").in_scope(|| {
98 tracing::trace!(message1 = ?MyDomainLogEvent::Foo, message2 = ?MyDomainLogEvent::Bar);
99 tracing::trace!(arbitrary_key = ?MyDomainLogEvent::Bar);
100 });
101 }
102
103 let events = tracing_capture_event_fields!({
105 emit_2_complex_payload_events();
106 });
107
108 let expected_events: Vec<Vec<(String, String)>> = vec![
110 vec![
111 ("message1".into(), MyDomainLogEvent::Foo.debug_fmt()),
112 ("message2".into(), MyDomainLogEvent::Bar.debug_fmt()),
113 ],
114 vec![("arbitrary_key".into(), MyDomainLogEvent::Bar.debug_fmt())],
115 ];
116
117 assert_eq!(events, expected_events);
118 }
119
120 #[test]
121 fn tracing_capture_event_fields__captures_debug_repr_of_custom_event_struct() {
122 fn emit_2_complex_payload_events() {
124 tracing::trace!(message = ?MyDomainLogEvent::Foo);
127 tracing::trace!(message = ?MyDomainLogEvent::Bar);
129 }
130
131 let events = tracing_capture_event_fields!({
133 emit_2_complex_payload_events();
134 });
135
136 let expected_events: Vec<Vec<(String, String)>> = vec![
138 vec![("message".into(), MyDomainLogEvent::Foo.debug_fmt())],
139 vec![("message".into(), MyDomainLogEvent::Bar.debug_fmt())],
140 ];
141
142 assert_eq!(events, expected_events);
143 }
144
145 #[test]
146 fn tracing_capture_events__can_collect_fields_values_off_of_returned_event() {
147 fn emit_2_complex_payload_events() {
149 tracing::info_span!("outermost span").in_scope(|| {
150 tracing::trace!(message1 = ?MyDomainLogEvent::Foo, message2 = ?MyDomainLogEvent::Bar);
151 tracing::trace!(arbitrary_key = ?MyDomainLogEvent::Bar);
152 });
153 }
154
155 let events = tracing_capture_events!({
157 emit_2_complex_payload_events();
158 });
159
160 let expected_events: Vec<Vec<(String, String)>> = vec![
162 vec![
163 ("message1".into(), MyDomainLogEvent::Foo.debug_fmt()),
164 ("message2".into(), MyDomainLogEvent::Bar.debug_fmt()),
165 ],
166 vec![("arbitrary_key".into(), MyDomainLogEvent::Bar.debug_fmt())],
167 ];
168
169 let events: Vec<FieldValueMap> = events.into_iter().map(|e| e.fields().clone()).collect();
170
171 assert_eq!(events, expected_events);
173 }
174}