Skip to content

Commit 601cdb8

Browse files
committed
temp
1 parent 96e0ed6 commit 601cdb8

File tree

9 files changed

+254
-60
lines changed

9 files changed

+254
-60
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use crate::next::Unstructured;
2+
use apollo_compiler::executable::Fragment;
3+
use apollo_compiler::{ExecutableDocument, Node};
4+
use crate::next::schema::Selectable;
5+
6+
pub(crate) trait ExecutableDocumentExt {
7+
fn random_fragment(&self, u: &mut Unstructured) -> arbitrary::Result<&Node<Fragment>> {
8+
let fragments = self.target().fragments.values().collect::<Vec<_>>();
9+
Ok(fragments[u.choose_index(fragments.len())?])
10+
}
11+
12+
fn random_fragment_of_type(
13+
&self,
14+
u: &mut Unstructured,
15+
selectable: &impl Selectable
16+
) -> arbitrary::Result<Option<&Node<Fragment>>> {
17+
let fragments = self.target().fragments.values().filter(|f|&f.selection_set.ty == selectable.name()).collect::<Vec<_>>();
18+
if fragments.is_empty() {
19+
return Ok(None)
20+
}
21+
Ok(Some(fragments[u.choose_index(fragments.len())?]))
22+
}
23+
fn target(&self) -> &ExecutableDocument;
24+
}
25+
26+
impl ExecutableDocumentExt for ExecutableDocument {
27+
fn target(&self) -> &ExecutableDocument {
28+
&self
29+
}
30+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub(crate) mod executable_document;

crates/apollo-smith/src/next/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod ast;
1010
mod mutations;
1111
mod schema;
1212
mod unstructured;
13+
mod executable;
1314

1415
#[derive(thiserror::Error, Debug)]
1516
pub enum Error {

crates/apollo-smith/src/next/mutations/add_anonymous_operation_definition.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::next::mutations::{ExecutableDocumentMutation, SchemaMutation};
1+
use crate::next::mutations::{ExecutableDocumentMutation};
22

33
use crate::next::unstructured::Unstructured;
44
use apollo_compiler::ast::{Definition, Document};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use crate::next::mutations::{ExecutableDocumentMutation};
2+
3+
use crate::next::unstructured::Unstructured;
4+
use apollo_compiler::ast::{Definition, Document};
5+
use apollo_compiler::{ExecutableDocument, Node, Schema};
6+
7+
pub(crate) struct AddFragmentDefiniton;
8+
9+
impl ExecutableDocumentMutation for AddFragmentDefiniton {
10+
fn apply(
11+
&self,
12+
u: &mut Unstructured,
13+
doc: &mut Document,
14+
schema: &Schema,
15+
executable_document: &ExecutableDocument,
16+
) -> arbitrary::Result<bool> {
17+
doc.definitions
18+
.push(Definition::FragmentDefinition(Node::new(
19+
u.arbitrary_fragment_definition(schema, executable_document)?,
20+
)));
21+
Ok(true)
22+
}
23+
fn is_valid(&self) -> bool {
24+
true
25+
}
26+
}

crates/apollo-smith/src/next/mutations/add_named_operation_definition.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::next::mutations::{ExecutableDocumentMutation, SchemaMutation};
1+
use crate::next::mutations::{ExecutableDocumentMutation};
22

33
use crate::next::unstructured::Unstructured;
44
use apollo_compiler::ast::{Definition, Document};

crates/apollo-smith/src/next/mutations/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ mod add_union_type_definition;
2525
mod remove_all_fields;
2626
mod remove_required_field;
2727
mod add_anonymous_operation_definition;
28+
mod add_fragment_definiton;
2829

2930
pub(crate) trait SchemaMutation {
3031
/// Apply the mutation to the document

crates/apollo-smith/src/next/schema/mod.rs

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use std::ops::Deref;
12
use std::sync::OnceLock;
23
use apollo_compiler::ast::{FieldDefinition, Name};
3-
use apollo_compiler::schema::{Component, ExtendedType, InterfaceType, ObjectType};
4+
use apollo_compiler::schema::{Component, ExtendedType, InterfaceType, ObjectType, UnionType};
45
use indexmap::IndexMap;
6+
use apollo_compiler::Schema;
57
use crate::next::Unstructured;
68

79
pub(crate) mod extended_type;
@@ -71,8 +73,12 @@ macro_rules! field_access {
7173
field_access!(ObjectType);
7274
field_access!(InterfaceType);
7375

74-
pub(crate) trait TypeHasFields {
76+
pub(crate) trait Selectable {
77+
78+
fn name(&self) -> &Name;
7579
fn fields(&self) -> &IndexMap<Name, Component<FieldDefinition>>;
80+
81+
fn random_specialization<'a>(&self, u: &mut Unstructured, schema: &'a Schema) -> arbitrary::Result<Option<&'a ExtendedType>>;
7682
fn random_field(&self, u: &mut Unstructured) -> arbitrary::Result<&Component<FieldDefinition>> {
7783
// Types always have at least one field
7884
let fields = self.fields().values().collect::<Vec<_>>();
@@ -81,25 +87,106 @@ pub(crate) trait TypeHasFields {
8187

8288
}
8389

84-
impl TypeHasFields for ObjectType {
90+
impl Selectable for ObjectType {
91+
fn name(&self) -> &Name {
92+
&self.name
93+
}
94+
95+
96+
8597
fn fields(&self) -> &IndexMap<Name, Component<FieldDefinition>> {
8698
&self.fields
8799
}
100+
101+
fn random_specialization<'a>(&self, _u: &mut Unstructured, _schema: &'a Schema) -> arbitrary::Result<Option<&'a ExtendedType>> {
102+
Ok(None)
103+
}
88104
}
89105

90-
impl TypeHasFields for InterfaceType {
106+
impl Selectable for &UnionType {
107+
fn name(&self) -> &Name {
108+
&self.name
109+
}
110+
111+
fn fields(&self) -> &IndexMap<Name, Component<FieldDefinition>> {
112+
static EMPTY: OnceLock<IndexMap<Name, Component<FieldDefinition>>> = OnceLock::new();
113+
&EMPTY.get_or_init(||Default::default())
114+
}
115+
116+
fn random_specialization<'a>(&self, u: &mut Unstructured, schema: &'a Schema) -> arbitrary::Result<Option<&'a ExtendedType>> {
117+
let members = self.members.iter().map(|name| schema.types.get(&name.name)).collect::<Vec<_>>();
118+
if members.is_empty() {
119+
Ok(None)
120+
}
121+
else {
122+
Ok(members[u.choose_index(members.len())?])
123+
}
124+
}
125+
}
126+
127+
impl Selectable for InterfaceType {
128+
fn name(&self) -> &Name {
129+
&self.name
130+
}
131+
91132
fn fields(&self) -> &IndexMap<Name, Component<FieldDefinition>> {
92133
&self.fields
93134
}
135+
136+
fn random_specialization<'a>(&self, u: &mut Unstructured, schema: &'a Schema) -> arbitrary::Result<Option<&'a ExtendedType>> {
137+
// An interface specialization is either an object or another interface that implements this interface
138+
let implements = schema
139+
.types
140+
.values()
141+
.filter(|ty| {
142+
match ty {
143+
ExtendedType::Object(o) => o.implements_interfaces.contains(&self.name),
144+
ExtendedType::Interface(i) => i.implements_interfaces.contains(&self.name),
145+
_=> return false,
146+
}
147+
})
148+
.collect::<Vec<_>>();
149+
if implements.is_empty() {
150+
Ok(None)
151+
}
152+
else {
153+
Ok(Some(implements[u.choose_index(implements.len())?]))
154+
}
155+
156+
157+
}
94158
}
95159

96-
impl TypeHasFields for ExtendedType {
160+
161+
impl Selectable for ExtendedType {
162+
fn name(&self) -> &Name {
163+
match self {
164+
ExtendedType::Scalar(scalar) => {&scalar.name}
165+
ExtendedType::Object(object_type) => {&object_type.name}
166+
ExtendedType::Interface(interface_type) => {&interface_type.name}
167+
ExtendedType::Union(union_type) => {&union_type.name}
168+
ExtendedType::Enum(enum_type) => {&enum_type.name}
169+
ExtendedType::InputObject(input_object) => {&input_object.name}
170+
}
171+
}
172+
173+
174+
97175
fn fields(&self) -> &IndexMap<Name, Component<FieldDefinition>> {
98176
static EMPTY: OnceLock<IndexMap<Name, Component<FieldDefinition>>> = OnceLock::new();
99177
match self {
100-
ExtendedType::Object(t) => t.fields(),
101-
ExtendedType::Interface(t) => t.fields(),
178+
ExtendedType::Object(t) => &t.fields,
179+
ExtendedType::Interface(t) => &t.fields,
102180
_ => &EMPTY.get_or_init(||Default::default()),
103181
}
104182
}
183+
184+
fn random_specialization<'a>(&self, u: &mut Unstructured, schema: &'a Schema) -> arbitrary::Result<Option<&'a ExtendedType>> {
185+
match self {
186+
ExtendedType::Object(object_type) => {object_type.deref().random_specialization(u, schema)}
187+
ExtendedType::Interface(interface_type) => { interface_type.deref().random_specialization(u, schema)}
188+
ExtendedType::Union(union_type) => { union_type.deref().random_specialization(u, schema)}
189+
_ => Ok(None)
190+
}
191+
}
105192
}

0 commit comments

Comments
 (0)