Add support for the canonical introspection query
Fixes https://github.com/graphql-rust/juniper/issues/307.
This commit is contained in:
parent
d5341e252a
commit
ba8cfbd105
13 changed files with 2825 additions and 21 deletions
docs/book
juniper
|
@ -2,20 +2,22 @@
|
||||||
- [Quickstart](quickstart.md)
|
- [Quickstart](quickstart.md)
|
||||||
|
|
||||||
- [Type System](types/index.md)
|
- [Type System](types/index.md)
|
||||||
- [Defining objects](types/objects/defining_objects.md)
|
|
||||||
- [Complex fields](types/objects/complex_fields.md)
|
- [Defining objects](types/objects/defining_objects.md)
|
||||||
- [Using contexts](types/objects/using_contexts.md)
|
- [Complex fields](types/objects/complex_fields.md)
|
||||||
- [Error handling](types/objects/error_handling.md)
|
- [Using contexts](types/objects/using_contexts.md)
|
||||||
- [Other types](types/other-index.md)
|
- [Error handling](types/objects/error_handling.md)
|
||||||
- [Enums](types/enums.md)
|
- [Other types](types/other-index.md)
|
||||||
- [Interfaces](types/interfaces.md)
|
- [Enums](types/enums.md)
|
||||||
- [Input objects](types/input_objects.md)
|
- [Interfaces](types/interfaces.md)
|
||||||
- [Scalars](types/scalars.md)
|
- [Input objects](types/input_objects.md)
|
||||||
- [Unions](types/unions.md)
|
- [Scalars](types/scalars.md)
|
||||||
|
- [Unions](types/unions.md)
|
||||||
|
|
||||||
- [Schemas and mutations](schema/schemas_and_mutations.md)
|
- [Schemas and mutations](schema/schemas_and_mutations.md)
|
||||||
|
|
||||||
- [Adding A Server](servers/index.md)
|
- [Adding A Server](servers/index.md)
|
||||||
|
|
||||||
- [Official Server Integrations](servers/official.md) - [Hyper](servers/hyper.md)
|
- [Official Server Integrations](servers/official.md) - [Hyper](servers/hyper.md)
|
||||||
- [Warp](servers/warp.md)
|
- [Warp](servers/warp.md)
|
||||||
- [Rocket](servers/rocket.md)
|
- [Rocket](servers/rocket.md)
|
||||||
|
@ -24,8 +26,12 @@
|
||||||
- [Third Party Integrations](servers/third-party.md)
|
- [Third Party Integrations](servers/third-party.md)
|
||||||
|
|
||||||
- [Advanced Topics](advanced/index.md)
|
- [Advanced Topics](advanced/index.md)
|
||||||
- [Non-struct objects](advanced/non_struct_objects.md)
|
|
||||||
- [Objects and generics](advanced/objects_and_generics.md)
|
- [Introspection](advanced/introspection.md)
|
||||||
- [Multiple operations per request](advanced/multiple_ops_per_request.md)
|
- [Non-struct objects](advanced/non_struct_objects.md)
|
||||||
|
- [Objects and generics](advanced/objects_and_generics.md)
|
||||||
|
- [Multiple operations per request](advanced/multiple_ops_per_request.md)
|
||||||
|
|
||||||
# - [Context switching]
|
# - [Context switching]
|
||||||
|
|
||||||
# - [Dynamic type system]
|
# - [Dynamic type system]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
The chapters below cover some more advanced scenarios.
|
The chapters below cover some more advanced scenarios.
|
||||||
|
|
||||||
|
- [Introspection](advanced/introspection.md)
|
||||||
- [Non-struct objects](advanced/non_struct_objects.md)
|
- [Non-struct objects](advanced/non_struct_objects.md)
|
||||||
- [Objects and generics](advanced/objects_and_generics.md)
|
- [Objects and generics](advanced/objects_and_generics.md)
|
||||||
- [Multiple operations per request](advanced/multiple_ops_per_request.md)
|
- [Multiple operations per request](advanced/multiple_ops_per_request.md)
|
||||||
|
|
73
docs/book/content/advanced/introspection.md
Normal file
73
docs/book/content/advanced/introspection.md
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
# Introspection
|
||||||
|
|
||||||
|
GraphQL defines a special built-in top-level field called `__schema`. Querying
|
||||||
|
for this field allows one to [introspect the schema](https://graphql.org/learn/introspection/)
|
||||||
|
at runtime to see what queries and mutations the GraphQL server supports.
|
||||||
|
|
||||||
|
Because introspection queries are just regular GraphQL queries, Juniper supports
|
||||||
|
them natively. For example, to get all the names of the types supported one
|
||||||
|
could execute the following query against Juniper:
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
__schema {
|
||||||
|
types {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Schema introspection output as JSON
|
||||||
|
|
||||||
|
Many client libraries and tools in the GraphQL ecosystem require a complete
|
||||||
|
representation of the server schema. Often this representation is in JSON and
|
||||||
|
referred to as `schema.json`. A complete representation of the schema can be
|
||||||
|
produced by issuing a specially crafted introspection query.
|
||||||
|
|
||||||
|
Juniper provides a convenience function to introspect the entire schema. The
|
||||||
|
result can then be converted to JSON for use with tools and libraries such as
|
||||||
|
[graphql-client](https://github.com/graphql-rust/graphql-client):
|
||||||
|
|
||||||
|
```rust
|
||||||
|
# // Only needed due to 2018 edition because the macro is not accessible.
|
||||||
|
# extern crate juniper;
|
||||||
|
# extern crate serde_json;
|
||||||
|
use juniper::{EmptyMutation, FieldResult, IntrospectionFormat};
|
||||||
|
|
||||||
|
// Define our schema.
|
||||||
|
|
||||||
|
#[derive(juniper::GraphQLObject)]
|
||||||
|
struct Example {
|
||||||
|
id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Context;
|
||||||
|
impl juniper::Context for Context {}
|
||||||
|
|
||||||
|
struct Query;
|
||||||
|
|
||||||
|
juniper::graphql_object!(Query: Context |&self| {
|
||||||
|
field example(&executor, id: String) -> FieldResult<Example> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
type Schema = juniper::RootNode<'static, Query, EmptyMutation<Context>>;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Create a context object.
|
||||||
|
let ctx = Context{};
|
||||||
|
|
||||||
|
// Run the built-in introspection query.
|
||||||
|
let (res, _errors) = juniper::introspect(
|
||||||
|
&Schema::new(Query, EmptyMutation::new()),
|
||||||
|
&ctx,
|
||||||
|
IntrospectionFormat::default(),
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
// Convert introspection result to json.
|
||||||
|
let json_result = serde_json::to_string_pretty(&res);
|
||||||
|
assert!(json_result.is_ok());
|
||||||
|
}
|
||||||
|
```
|
|
@ -33,8 +33,8 @@ use juniper::{FieldResult};
|
||||||
# struct DatabasePool;
|
# struct DatabasePool;
|
||||||
# impl DatabasePool {
|
# impl DatabasePool {
|
||||||
# fn get_connection(&self) -> FieldResult<DatabasePool> { Ok(DatabasePool) }
|
# fn get_connection(&self) -> FieldResult<DatabasePool> { Ok(DatabasePool) }
|
||||||
# fn find_human(&self, id: &str) -> FieldResult<Human> { Err("")? }
|
# fn find_human(&self, _id: &str) -> FieldResult<Human> { Err("")? }
|
||||||
# fn insert_human(&self, human: &NewHuman) -> FieldResult<Human> { Err("")? }
|
# fn insert_human(&self, _human: &NewHuman) -> FieldResult<Human> { Err("")? }
|
||||||
# }
|
# }
|
||||||
|
|
||||||
#[derive(juniper::GraphQLEnum)]
|
#[derive(juniper::GraphQLEnum)]
|
||||||
|
@ -114,12 +114,14 @@ juniper::graphql_object!(Mutation: Context |&self| {
|
||||||
// Request queries can be executed against a RootNode.
|
// Request queries can be executed against a RootNode.
|
||||||
type Schema = juniper::RootNode<'static, Query, Mutation>;
|
type Schema = juniper::RootNode<'static, Query, Mutation>;
|
||||||
|
|
||||||
# fn main() { }
|
# fn main() {
|
||||||
|
# let _ = Schema::new(Query, Mutation{});
|
||||||
|
# }
|
||||||
```
|
```
|
||||||
|
|
||||||
We now have a very simple but functional schema for a GraphQL server!
|
We now have a very simple but functional schema for a GraphQL server!
|
||||||
|
|
||||||
To actually serve the schema, see the guides for our various [server integrations](./servers/index.md).
|
To actually serve the schema, see the guides for our various [server integrations](./servers/index.md).
|
||||||
|
|
||||||
You can also invoke the executor directly to get a result for a query:
|
You can also invoke the executor directly to get a result for a query:
|
||||||
|
|
||||||
|
@ -129,6 +131,7 @@ You can invoke `juniper::execute` directly to run a GraphQL query:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
# // Only needed due to 2018 edition because the macro is not accessible.
|
# // Only needed due to 2018 edition because the macro is not accessible.
|
||||||
|
# #[macro_use]
|
||||||
# extern crate juniper;
|
# extern crate juniper;
|
||||||
use juniper::{FieldResult, Variables, EmptyMutation};
|
use juniper::{FieldResult, Variables, EmptyMutation};
|
||||||
|
|
||||||
|
@ -172,7 +175,7 @@ fn main() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
res,
|
res,
|
||||||
graphql_value!({
|
graphql_value!({
|
||||||
"favoriteEpisode": "NEW_HONE",
|
"favoriteEpisode": "NEW_HOPE",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
extern crate skeptic;
|
extern crate skeptic;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let files = skeptic::markdown_files_of_directory("../content/types");
|
let files = skeptic::markdown_files_of_directory("../content/");
|
||||||
skeptic::generate_doc_tests(&files);
|
skeptic::generate_doc_tests(&files);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
- The minimum required Rust version is now `1.30.0`.
|
- The minimum required Rust version is now `1.30.0`.
|
||||||
- The `ScalarValue` custom derive has been renamed to `GraphQLScalarValue`.
|
- The `ScalarValue` custom derive has been renamed to `GraphQLScalarValue`.
|
||||||
|
- Added built-in support for the canonical schema introspection query via
|
||||||
|
`juniper::introspect()`. [#307](https://github.com/graphql-rust/juniper/issues/307)
|
||||||
- Fix introspection query validity
|
- Fix introspection query validity
|
||||||
The DirectiveLocation::InlineFragment had an invalid literal value,
|
The DirectiveLocation::InlineFragment had an invalid literal value,
|
||||||
which broke third party tools like apollo cli.
|
which broke third party tools like apollo cli.
|
||||||
- Added GraphQL Playground integration
|
- Added GraphQL Playground integration
|
||||||
The DirectiveLocation::InlineFragment had an invalid literal value,
|
The DirectiveLocation::InlineFragment had an invalid literal value,
|
||||||
which broke third party tools like apollo cli.
|
which broke third party tools like apollo cli.
|
||||||
- The return type of `value::object::Object::iter/iter_mut` has changed to `impl Iter` [#312](https://github.com/graphql-rust/juniper/pull/312)
|
- The return type of `value::object::Object::iter/iter_mut` has changed to `impl Iter` [#312](https://github.com/graphql-rust/juniper/pull/312)
|
||||||
|
|
||||||
# [0.11.1] 2018-12-19
|
# [0.11.1] 2018-12-19
|
||||||
|
|
19
juniper/src/introspection/mod.rs
Normal file
19
juniper/src/introspection/mod.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/// From <https://github.com/graphql/graphql-js/blob/8c96dc8276f2de27b8af9ffbd71a4597d483523f/src/utilities/introspectionQuery.js#L21>s
|
||||||
|
pub(crate) const INTROSPECTION_QUERY: &str = include_str!("./query.graphql");
|
||||||
|
pub(crate) const INTROSPECTION_QUERY_WITHOUT_DESCRIPTIONS: &str =
|
||||||
|
include_str!("./query_without_descriptions.graphql");
|
||||||
|
|
||||||
|
/// The desired GraphQL introspection format for the canonical query
|
||||||
|
/// (<https://github.com/graphql/graphql-js/blob/8c96dc8276f2de27b8af9ffbd71a4597d483523f/src/utilities/introspectionQuery.js#L21>)
|
||||||
|
pub enum IntrospectionFormat {
|
||||||
|
/// The canonical GraphQL introspection query.
|
||||||
|
All,
|
||||||
|
/// The canonical GraphQL introspection query without descriptions.
|
||||||
|
WithoutDescriptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for IntrospectionFormat {
|
||||||
|
fn default() -> Self {
|
||||||
|
IntrospectionFormat::All
|
||||||
|
}
|
||||||
|
}
|
96
juniper/src/introspection/query.graphql
Normal file
96
juniper/src/introspection/query.graphql
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
query IntrospectionQuery {
|
||||||
|
__schema {
|
||||||
|
queryType {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
mutationType {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
subscriptionType {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
types {
|
||||||
|
...FullType
|
||||||
|
}
|
||||||
|
directives {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
locations
|
||||||
|
args {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragment FullType on __Type {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
description
|
||||||
|
fields(includeDeprecated: true) {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
args {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
type {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
isDeprecated
|
||||||
|
deprecationReason
|
||||||
|
}
|
||||||
|
inputFields {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
interfaces {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
enumValues(includeDeprecated: true) {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
isDeprecated
|
||||||
|
deprecationReason
|
||||||
|
}
|
||||||
|
possibleTypes {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragment InputValue on __InputValue {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
type {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
defaultValue
|
||||||
|
}
|
||||||
|
fragment TypeRef on __Type {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
91
juniper/src/introspection/query_without_descriptions.graphql
Normal file
91
juniper/src/introspection/query_without_descriptions.graphql
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
query IntrospectionQuery {
|
||||||
|
__schema {
|
||||||
|
queryType {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
mutationType {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
subscriptionType {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
types {
|
||||||
|
...FullType
|
||||||
|
}
|
||||||
|
directives {
|
||||||
|
name
|
||||||
|
locations
|
||||||
|
args {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragment FullType on __Type {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
fields(includeDeprecated: true) {
|
||||||
|
name
|
||||||
|
args {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
type {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
isDeprecated
|
||||||
|
deprecationReason
|
||||||
|
}
|
||||||
|
inputFields {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
interfaces {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
enumValues(includeDeprecated: true) {
|
||||||
|
name
|
||||||
|
isDeprecated
|
||||||
|
deprecationReason
|
||||||
|
}
|
||||||
|
possibleTypes {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragment InputValue on __InputValue {
|
||||||
|
name
|
||||||
|
type {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
defaultValue
|
||||||
|
}
|
||||||
|
fragment TypeRef on __Type {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -127,6 +127,7 @@ mod value;
|
||||||
mod macros;
|
mod macros;
|
||||||
mod ast;
|
mod ast;
|
||||||
mod executor;
|
mod executor;
|
||||||
|
mod introspection;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub(crate) mod schema;
|
pub(crate) mod schema;
|
||||||
mod types;
|
mod types;
|
||||||
|
@ -151,6 +152,7 @@ mod executor_tests;
|
||||||
pub use util::to_camel_case;
|
pub use util::to_camel_case;
|
||||||
|
|
||||||
use executor::execute_validated_query;
|
use executor::execute_validated_query;
|
||||||
|
use introspection::{INTROSPECTION_QUERY, INTROSPECTION_QUERY_WITHOUT_DESCRIPTIONS};
|
||||||
use parser::{parse_document_source, ParseError, Spanning};
|
use parser::{parse_document_source, ParseError, Spanning};
|
||||||
use validation::{validate_input_values, visit_all_rules, ValidatorContext};
|
use validation::{validate_input_values, visit_all_rules, ValidatorContext};
|
||||||
|
|
||||||
|
@ -162,6 +164,7 @@ pub use executor::{
|
||||||
Context, ExecutionError, ExecutionResult, Executor, FieldError, FieldResult, FromContext,
|
Context, ExecutionError, ExecutionResult, Executor, FieldError, FieldResult, FromContext,
|
||||||
IntoFieldError, IntoResolvable, Registry, Variables,
|
IntoFieldError, IntoResolvable, Registry, Variables,
|
||||||
};
|
};
|
||||||
|
pub use introspection::IntrospectionFormat;
|
||||||
pub use schema::meta;
|
pub use schema::meta;
|
||||||
pub use schema::model::RootNode;
|
pub use schema::model::RootNode;
|
||||||
pub use types::base::{Arguments, GraphQLType, TypeKind};
|
pub use types::base::{Arguments, GraphQLType, TypeKind};
|
||||||
|
@ -219,6 +222,30 @@ where
|
||||||
execute_validated_query(document, operation_name, root_node, variables, context)
|
execute_validated_query(document, operation_name, root_node, variables, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Execute the reference introspection query in the provided schema
|
||||||
|
pub fn introspect<'a, S, CtxT, QueryT, MutationT>(
|
||||||
|
root_node: &'a RootNode<QueryT, MutationT, S>,
|
||||||
|
context: &CtxT,
|
||||||
|
format: IntrospectionFormat,
|
||||||
|
) -> Result<(Value<S>, Vec<ExecutionError<S>>), GraphQLError<'a>>
|
||||||
|
where
|
||||||
|
S: ScalarValue,
|
||||||
|
for<'b> &'b S: ScalarRefValue<'b>,
|
||||||
|
QueryT: GraphQLType<S, Context = CtxT>,
|
||||||
|
MutationT: GraphQLType<S, Context = CtxT>,
|
||||||
|
{
|
||||||
|
execute(
|
||||||
|
match format {
|
||||||
|
IntrospectionFormat::All => INTROSPECTION_QUERY,
|
||||||
|
IntrospectionFormat::WithoutDescriptions => INTROSPECTION_QUERY_WITHOUT_DESCRIPTIONS,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
root_node,
|
||||||
|
&Variables::new(),
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
|
impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
|
||||||
fn from(f: Spanning<ParseError<'a>>) -> GraphQLError<'a> {
|
fn from(f: Spanning<ParseError<'a>>) -> GraphQLError<'a> {
|
||||||
GraphQLError::ParseError(f)
|
GraphQLError::ParseError(f)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use super::schema_introspection::*;
|
||||||
use executor::Variables;
|
use executor::Variables;
|
||||||
|
use introspection::IntrospectionFormat;
|
||||||
use schema::model::RootNode;
|
use schema::model::RootNode;
|
||||||
use tests::model::Database;
|
use tests::model::Database;
|
||||||
use types::scalars::EmptyMutation;
|
use types::scalars::EmptyMutation;
|
||||||
|
@ -229,3 +231,23 @@ fn test_introspection_possible_types() {
|
||||||
|
|
||||||
assert_eq!(possible_types, vec!["Human", "Droid"].into_iter().collect());
|
assert_eq!(possible_types, vec!["Human", "Droid"].into_iter().collect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_builtin_introspection_query() {
|
||||||
|
let database = Database::new();
|
||||||
|
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
|
||||||
|
|
||||||
|
let result = ::introspect(&schema, &database, IntrospectionFormat::default());
|
||||||
|
let expected = schema_introspection_result();
|
||||||
|
assert_eq!(result, Ok((expected, vec![])));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_builtin_introspection_query_without_descriptions() {
|
||||||
|
let database = Database::new();
|
||||||
|
let schema = RootNode::new(&database, EmptyMutation::<Database>::new());
|
||||||
|
|
||||||
|
let result = ::introspect(&schema, &database, IntrospectionFormat::WithoutDescriptions);
|
||||||
|
let expected = schema_introspection_result_without_descriptions();
|
||||||
|
assert_eq!(result, Ok((expected, vec![])));
|
||||||
|
}
|
||||||
|
|
|
@ -7,4 +7,6 @@ pub mod model;
|
||||||
mod query_tests;
|
mod query_tests;
|
||||||
mod schema;
|
mod schema;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
mod schema_introspection;
|
||||||
|
#[cfg(test)]
|
||||||
mod type_info_tests;
|
mod type_info_tests;
|
||||||
|
|
2462
juniper/src/tests/schema_introspection.rs
Normal file
2462
juniper/src/tests/schema_introspection.rs
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue