substrait_explain/
fixtures.rs1use crate::extensions::simple::ExtensionKind;
4use crate::extensions::{ExtensionRegistry, SimpleExtensions};
5use crate::format;
6use crate::parser::{MessageParseError, Parser, ScopedParse};
7use crate::textify::foundation::{ErrorAccumulator, ErrorList};
8use crate::textify::plan::PlanWriter;
9use crate::textify::{ErrorQueue, OutputOptions, Scope, ScopedContext, Textify};
10
11pub struct TestContext {
12 pub options: OutputOptions,
13 pub extensions: SimpleExtensions,
14 pub extension_registry: ExtensionRegistry,
15}
16
17impl Default for TestContext {
18 fn default() -> Self {
19 Self::new()
20 }
21}
22
23impl TestContext {
24 pub fn new() -> Self {
25 Self {
26 options: OutputOptions::default(),
27 extensions: SimpleExtensions::new(),
28 extension_registry: ExtensionRegistry::new(),
29 }
30 }
31
32 pub fn with_options(mut self, options: OutputOptions) -> Self {
33 self.options = options;
34 self
35 }
36
37 pub fn with_urn(mut self, anchor: u32, urn: &str) -> Self {
38 self.extensions
39 .add_extension_urn(urn.to_string(), anchor)
40 .unwrap();
41 self
42 }
43
44 pub fn with_function(mut self, urn: u32, anchor: u32, name: impl Into<String>) -> Self {
45 assert!(self.extensions.find_urn(urn).is_ok());
46 self.extensions
47 .add_extension(ExtensionKind::Function, urn, anchor, name.into())
48 .unwrap();
49 self
50 }
51
52 pub fn with_type(mut self, urn: u32, anchor: u32, name: impl Into<String>) -> Self {
53 assert!(self.extensions.find_urn(urn).is_ok());
54 self.extensions
55 .add_extension(ExtensionKind::Type, urn, anchor, name.into())
56 .unwrap();
57 self
58 }
59
60 pub fn with_type_variation(mut self, urn: u32, anchor: u32, name: impl Into<String>) -> Self {
61 assert!(self.extensions.find_urn(urn).is_ok());
62 self.extensions
63 .add_extension(ExtensionKind::TypeVariation, urn, anchor, name.into())
64 .unwrap();
65 self
66 }
67
68 pub fn scope<'e, E: ErrorAccumulator>(&'e self, errors: &'e E) -> impl Scope + 'e {
69 ScopedContext::new(
70 &self.options,
71 errors,
72 &self.extensions,
73 &self.extension_registry,
74 )
75 }
76
77 pub fn textify<T: Textify>(&self, t: &T) -> (String, ErrorList) {
78 let errors = ErrorQueue::default();
79 let mut output = String::new();
80
81 let scope = self.scope(&errors);
82 t.textify(&scope, &mut output).unwrap();
83
84 let evec = errors.into_iter().collect();
85 (output, ErrorList(evec))
86 }
87
88 pub fn textify_no_errors<T: Textify>(&self, t: &T) -> String {
89 let (s, errs) = self.textify(t);
90 assert!(errs.is_empty(), "{} Errors: {}", errs.0.len(), errs.0[0]);
91 s
92 }
93
94 pub fn parse<T: ScopedParse>(&self, input: &str) -> Result<T, MessageParseError> {
95 T::parse(&self.extensions, input)
96 }
97}
98
99pub fn roundtrip_plan(input: &str) {
102 let plan = Parser::parse(input).unwrap_or_else(|e| {
104 println!("Error parsing plan:\n{e}");
105 panic!("{e}");
106 });
107
108 let (actual, errors) = format(&plan);
110
111 if !errors.is_empty() {
113 println!("Formatting errors:");
114 for error in errors {
115 println!(" {error}");
116 }
117 panic!("Formatting errors occurred");
118 }
119
120 assert_eq!(
122 actual.trim(),
123 input.trim(),
124 "Expected:\n---\n{}\n---\nActual:\n---\n{}\n---",
125 input.trim(),
126 actual.trim()
127 );
128}
129
130pub fn roundtrip_plan_with_verbose(input: &str, verbose_input: &str) {
133 let default_registry = ExtensionRegistry::new();
134
135 let simple_plan = Parser::parse(input).unwrap_or_else(|e| {
137 println!("Error parsing simple plan:\n{e}");
138 panic!("{e}");
139 });
140
141 let verbose_plan = Parser::parse(verbose_input).unwrap_or_else(|e| {
143 println!("Error parsing verbose plan:\n{e}");
144 panic!("{e}");
145 });
146
147 let verbose_options = OutputOptions::verbose();
149 let (simple_verbose_writer, simple_verbose_errors) =
150 PlanWriter::<ErrorQueue>::new(&verbose_options, &simple_plan, &default_registry);
151 let simple_verbose_actual = format!("{simple_verbose_writer}");
152 simple_verbose_errors
153 .errs()
154 .expect("Errors during simple -> verbose conversion");
155
156 let (verbose_verbose_writer, verbose_verbose_errors) =
157 PlanWriter::<ErrorQueue>::new(&verbose_options, &verbose_plan, &default_registry);
158 let verbose_verbose_actual = format!("{verbose_verbose_writer}");
159 verbose_verbose_errors
160 .errs()
161 .expect("Errors during verbose -> verbose conversion");
162
163 assert_eq!(
164 simple_verbose_actual.trim(),
165 verbose_verbose_actual.trim(),
166 "Expected verbose outputs to match:\n---\n{}\n---\n---\n{}\n---",
167 simple_verbose_actual.trim(),
168 verbose_verbose_actual.trim()
169 );
170
171 let simple_options = OutputOptions::default();
173 let (simple_simple_writer, simple_simple_errors) =
174 PlanWriter::<ErrorQueue>::new(&simple_options, &simple_plan, &default_registry);
175 let simple_simple_actual = format!("{simple_simple_writer}");
176 simple_simple_errors
177 .errs()
178 .expect("Errors during simple -> simple conversion");
179
180 let (verbose_simple_writer, verbose_simple_errors) =
181 PlanWriter::<ErrorQueue>::new(&simple_options, &verbose_plan, &default_registry);
182 let verbose_simple_actual = format!("{verbose_simple_writer}");
183 verbose_simple_errors
184 .errs()
185 .expect("Errors during verbose -> simple conversion");
186
187 assert_eq!(
188 simple_simple_actual.trim(),
189 verbose_simple_actual.trim(),
190 "Expected simple outputs to match:\n---\n{}\n---\n---\n{}\n---",
191 simple_simple_actual.trim(),
192 verbose_simple_actual.trim()
193 );
194}