1#![doc = include_str!("../README.md")]
2
3pub(crate) mod argument;
4pub(crate) mod description;
5pub(crate) mod directive;
6pub(crate) mod document;
7pub(crate) mod enum_;
8pub(crate) mod field;
9pub(crate) mod fragment;
10pub mod generators;
11pub(crate) mod implements_graph;
12pub(crate) mod input_object;
13pub(crate) mod input_value;
14pub(crate) mod interface;
15pub(crate) mod name;
16pub(crate) mod object;
17pub(crate) mod operation;
18pub mod random;
19pub(crate) mod response;
20pub(crate) mod scalar;
21pub(crate) mod schema;
22pub(crate) mod selection_set;
23#[cfg(test)]
24pub(crate) mod snapshot_tests;
25pub(crate) mod ty;
26pub(crate) mod union;
27pub(crate) mod variable;
28
29use indexmap::IndexMap;
30use std::collections::HashSet;
31use std::fmt::Debug;
32
33#[derive(Debug, Clone, thiserror::Error)]
34pub enum FromError {
35 #[error("parse tree is missing a node")]
36 MissingNode,
37 #[error("invalid i32")]
38 ParseIntError(#[from] std::num::ParseIntError),
39 #[error("invalid f64")]
40 ParseFloatError(#[from] std::num::ParseFloatError),
41 #[error("invalid boolean")]
42 ParseBoolError(#[from] std::str::ParseBoolError),
43}
44
45use apollo_compiler::coordinate::TypeAttributeCoordinate;
46pub use arbitrary::Result;
47pub use arbitrary::Unstructured;
48use argument::Argument;
49pub use directive::DirectiveDef;
50pub use document::Document;
51pub use enum_::EnumTypeDef;
52use field::FieldDef;
53pub use fragment::FragmentDef;
54pub use generators::BooleanGenerator;
55pub use generators::FloatGenerator;
56pub use generators::Generator;
57pub use generators::Generators;
58pub use generators::IdGenerator;
59pub use generators::IntGenerator;
60pub use generators::StringGenerator;
61pub use input_object::InputObjectTypeDef;
62pub use interface::InterfaceTypeDef;
63use name::Name;
64pub use object::ObjectTypeDef;
65pub use operation::OperationDef;
66pub use random::RandProvider;
67pub use random::RandomProvider;
68pub use random::ResponseError;
69pub use response::ResponseBuilder;
70pub use scalar::ScalarTypeDef;
71pub use schema::SchemaDef;
72pub use serde_json_bytes::Value;
73use ty::Ty;
74pub use union::UnionTypeDef;
75
76const DEFAULT_MAX: usize = 50;
77
78pub struct DocumentBuilder<'a> {
97 pub(crate) u: &'a mut Unstructured<'a>,
98 pub(crate) input_object_type_defs: Vec<InputObjectTypeDef>,
99 pub(crate) object_type_defs: Vec<ObjectTypeDef>,
100 pub(crate) interface_type_defs: Vec<InterfaceTypeDef>,
101 pub(crate) union_type_defs: Vec<UnionTypeDef>,
102 pub(crate) enum_type_defs: Vec<EnumTypeDef>,
103 pub(crate) scalar_type_defs: Vec<ScalarTypeDef>,
104 pub(crate) schema_def: Option<SchemaDef>,
105 pub(crate) directive_defs: Vec<DirectiveDef>,
106 pub(crate) operation_defs: Vec<OperationDef>,
107 pub(crate) fragment_defs: Vec<FragmentDef>,
108 pub(crate) implements_graph: implements_graph::ImplementsGraph,
110 pub(crate) stack: Vec<Box<dyn StackedEntity>>,
112 pub(crate) chosen_arguments: IndexMap<TypeAttributeCoordinate, Vec<Argument>>,
114 pub(crate) used_type_names: HashSet<String>,
115 max_scalar_types: usize,
117 max_enum_types: usize,
118 max_interface_types: usize,
119 max_object_types: usize,
120 max_union_types: usize,
121 max_input_object_types: usize,
122 max_fragment_definitions: usize,
123 max_directive_definitions: usize,
124 max_operation_definitions: usize,
125}
126
127impl Debug for DocumentBuilder<'_> {
128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129 f.debug_struct("DocumentBuilder")
130 .field("input_object_type_defs", &self.input_object_type_defs)
131 .field("object_type_defs", &self.object_type_defs)
132 .field("interface_type_defs", &self.interface_type_defs)
133 .field("union_type_defs", &self.union_type_defs)
134 .field("enum_type_defs", &self.enum_type_defs)
135 .field("scalar_type_defs", &self.scalar_type_defs)
136 .field("schema_def", &self.schema_def)
137 .field("directive_defs", &self.directive_defs)
138 .field("operation_defs", &self.operation_defs)
139 .field("fragment_defs", &self.fragment_defs)
140 .finish()
141 }
142}
143
144impl<'a> DocumentBuilder<'a> {
145 pub fn new(u: &'a mut Unstructured<'a>) -> Self {
147 Self {
148 u,
149 object_type_defs: Vec::new(),
150 interface_type_defs: Vec::new(),
151 enum_type_defs: Vec::new(),
152 schema_def: None,
153 directive_defs: Vec::new(),
154 operation_defs: Vec::new(),
155 fragment_defs: Vec::new(),
156 scalar_type_defs: Vec::new(),
157 union_type_defs: Vec::new(),
158 input_object_type_defs: Vec::new(),
159 implements_graph: implements_graph::ImplementsGraph::new(),
160 stack: Vec::new(),
161 chosen_arguments: IndexMap::new(),
162 used_type_names: HashSet::new(),
163 max_scalar_types: DEFAULT_MAX,
164 max_enum_types: DEFAULT_MAX,
165 max_interface_types: DEFAULT_MAX,
166 max_object_types: DEFAULT_MAX,
167 max_union_types: DEFAULT_MAX,
168 max_input_object_types: DEFAULT_MAX,
169 max_fragment_definitions: DEFAULT_MAX,
170 max_directive_definitions: DEFAULT_MAX,
171 max_operation_definitions: DEFAULT_MAX,
172 }
173 }
174
175 pub fn max_scalar_types(mut self, max: usize) -> Self {
177 self.max_scalar_types = max;
178 self
179 }
180
181 pub fn max_enum_types(mut self, max: usize) -> Self {
183 self.max_enum_types = max;
184 self
185 }
186
187 pub fn max_interface_types(mut self, max: usize) -> Self {
189 self.max_interface_types = max;
190 self
191 }
192
193 pub fn max_object_types(mut self, max: usize) -> Self {
195 self.max_object_types = max;
196 self
197 }
198
199 pub fn max_union_types(mut self, max: usize) -> Self {
201 self.max_union_types = max;
202 self
203 }
204
205 pub fn max_input_object_types(mut self, max: usize) -> Self {
207 self.max_input_object_types = max;
208 self
209 }
210
211 pub fn max_fragment_definitions(mut self, max: usize) -> Self {
213 self.max_fragment_definitions = max;
214 self
215 }
216
217 pub fn max_directive_definitions(mut self, max: usize) -> Self {
219 self.max_directive_definitions = max;
220 self
221 }
222
223 pub fn max_operation_definitions(mut self, max: usize) -> Self {
225 self.max_operation_definitions = max;
226 self
227 }
228
229 pub fn build(mut self) -> Result<Document> {
232 for _ in 0..self.u.int_in_range(1..=self.max_scalar_types)? {
233 let scalar_type_def = self.scalar_type_definition()?;
234 self.scalar_type_defs.push(scalar_type_def);
235 }
236
237 for _ in 0..self.u.int_in_range(1..=self.max_enum_types)? {
238 let enum_type_def = self.enum_type_definition()?;
239 self.enum_type_defs.push(enum_type_def);
240 }
241
242 for _ in 0..self.u.int_in_range(1..=self.max_interface_types)? {
243 let def = self.interface_type_definition()?;
244 self.implements_graph.node_for(&def.name);
245 for parent in &def.interfaces {
246 self.implements_graph.add_edge(&def.name, parent);
247 }
248 self.interface_type_defs.push(def);
249 }
250 self.backfill_inherited_interface_fields();
251
252 for _ in 0..self.u.int_in_range(1..=self.max_object_types)? {
253 let def = self.object_type_definition()?;
254 self.implements_graph.node_for(&def.name);
255 for parent in &def.implements_interfaces {
256 self.implements_graph.add_edge(&def.name, parent);
257 }
258 self.object_type_defs.push(def);
259 }
260 self.backfill_inherited_object_fields();
261
262 for _ in 0..self.u.int_in_range(1..=self.max_union_types)? {
263 let union_type_def = self.union_type_definition()?;
264 self.union_type_defs.push(union_type_def);
265 }
266
267 for _ in 0..self.u.int_in_range(1..=self.max_input_object_types)? {
268 let input_object_type_def = self.input_object_type_definition()?;
269 self.input_object_type_defs.push(input_object_type_def);
270 }
271
272 for _ in 0..self.u.int_in_range(1..=self.max_fragment_definitions)? {
273 let fragment_def = self.fragment_definition()?;
274 self.fragment_defs.push(fragment_def);
275 }
276
277 for _ in 0..self.u.int_in_range(1..=self.max_directive_definitions)? {
278 let directive_def = self.directive_def()?;
279 self.directive_defs.push(directive_def);
280 }
281
282 let schema_def = self.schema_definition()?;
283 self.schema_def = Some(schema_def);
284
285 let num_ops = self.u.int_in_range(1..=self.max_operation_definitions)?;
289 let require_named = num_ops > 1;
290 for _ in 0..num_ops {
291 let operation_def = self.operation_definition_in_document(require_named)?;
292 if let Some(operation_def) = operation_def {
293 self.operation_defs.push(operation_def);
294 }
295 }
296
297 self.prune_unused_fragments();
298
299 Ok(Document {
300 schema_definition: self.schema_def,
301 object_type_definitions: self.object_type_defs,
302 interface_type_definitions: self.interface_type_defs,
303 enum_type_definitions: self.enum_type_defs,
304 directive_definitions: self.directive_defs,
305 operation_definitions: self.operation_defs,
306 fragment_definitions: self.fragment_defs,
307 scalar_type_definitions: self.scalar_type_defs,
308 union_type_definitions: self.union_type_defs,
309 input_object_type_definitions: self.input_object_type_defs,
310 })
311 }
312
313 pub fn with_document(u: &'a mut Unstructured<'a>, document: Document) -> Result<Self> {
316 let mut implements_graph = implements_graph::ImplementsGraph::new();
317 for itf in &document.interface_type_definitions {
318 implements_graph.node_for(&itf.name);
319 for parent in &itf.interfaces {
320 implements_graph.add_edge(&itf.name, parent);
321 }
322 }
323 for obj in &document.object_type_definitions {
324 implements_graph.node_for(&obj.name);
325 for parent in &obj.implements_interfaces {
326 implements_graph.add_edge(&obj.name, parent);
327 }
328 }
329 let mut builder = Self {
330 u,
331 object_type_defs: document.object_type_definitions,
332 interface_type_defs: document.interface_type_definitions,
333 enum_type_defs: document.enum_type_definitions,
334 schema_def: document.schema_definition,
335 directive_defs: document.directive_definitions,
336 operation_defs: document.operation_definitions,
337 fragment_defs: document.fragment_definitions,
338 scalar_type_defs: document.scalar_type_definitions,
339 union_type_defs: document.union_type_definitions,
340 input_object_type_defs: document.input_object_type_definitions,
341 implements_graph,
342 stack: Vec::new(),
343 chosen_arguments: IndexMap::new(),
344 used_type_names: HashSet::new(),
345 max_scalar_types: DEFAULT_MAX,
346 max_enum_types: DEFAULT_MAX,
347 max_interface_types: DEFAULT_MAX,
348 max_object_types: DEFAULT_MAX,
349 max_union_types: DEFAULT_MAX,
350 max_input_object_types: DEFAULT_MAX,
351 max_fragment_definitions: DEFAULT_MAX,
352 max_directive_definitions: DEFAULT_MAX,
353 max_operation_definitions: DEFAULT_MAX,
354 };
355 for def in &builder.object_type_defs {
356 builder.used_type_names.insert(def.name.name.clone());
357 }
358 for def in &builder.interface_type_defs {
359 builder.used_type_names.insert(def.name.name.clone());
360 }
361 for def in &builder.enum_type_defs {
362 builder.used_type_names.insert(def.name.name.clone());
363 }
364 for def in &builder.directive_defs {
365 builder.used_type_names.insert(def.name.name.clone());
366 }
367 for def in &builder.union_type_defs {
368 builder.used_type_names.insert(def.name.name.clone());
369 }
370 for def in &builder.input_object_type_defs {
371 builder.used_type_names.insert(def.name.name.clone());
372 }
373 for def in &builder.scalar_type_defs {
374 builder.used_type_names.insert(def.name.name.clone());
375 }
376 for def in &builder.fragment_defs {
377 builder.used_type_names.insert(def.name.name.clone());
378 }
379 for def in &builder.operation_defs {
380 if let Some(name) = &def.name {
381 builder.used_type_names.insert(name.name.clone());
382 }
383 }
384
385 Ok(builder)
386 }
387
388 pub fn input_exhausted(&self) -> bool {
390 self.u.is_empty()
391 }
392
393 pub(crate) fn stack_ty(&mut self, ty: &Ty) -> bool {
394 if ty.is_builtin() {
395 return false;
396 }
397 let type_name = ty.name();
398
399 if let Some(object_ty) = self
400 .object_type_defs
401 .iter()
402 .find(|object_ty_def| &object_ty_def.name == type_name)
403 .cloned()
404 {
405 self.stack.push(Box::new(object_ty));
406 true
407 } else if let Some(itf_type) = self
408 .interface_type_defs
409 .iter()
410 .find(|itf_type_def| &itf_type_def.name == type_name)
411 .cloned()
412 {
413 self.stack.push(Box::new(itf_type));
414 true
415 } else if let Some(_enum_ty) = self
416 .enum_type_defs
417 .iter()
418 .find(|object_ty_def| &object_ty_def.name == type_name)
419 .cloned()
420 {
421 false
422 } else {
423 todo!("'{:?}' need to implement for union, scalar, ...", type_name);
424 }
425 }
426
427 fn prune_unused_fragments(&mut self) {
435 let reachable =
436 fragment::reachable_fragment_names(&self.operation_defs, &self.fragment_defs);
437 self.fragment_defs.retain(|f| reachable.contains(&f.name));
438 }
439}
440
441pub(crate) trait StackedEntity {
442 fn name(&self) -> &Name;
443 fn fields_def(&self) -> &[FieldDef];
444}