1 module graphql.starwars.validation; 2 3 import std.typecons : Nullable, nullable; 4 import std.format : format; 5 import std.exception; 6 import std.stdio; 7 8 import vibe.data.json; 9 10 import graphql.validation.exception; 11 import graphql.constants; 12 import graphql.parser; 13 import graphql.builder; 14 import graphql.lexer; 15 import graphql.ast; 16 import graphql.graphql; 17 import graphql.helper; 18 import graphql.starwars.data; 19 import graphql.starwars.schema; 20 import graphql.starwars.types; 21 import graphql.validation.querybased; 22 import graphql.validation.schemabased; 23 24 @safe: 25 26 void test(string s) { 27 auto graphqld = new GraphQLD!(StarWarsSchema); 28 auto l = Lexer(s); 29 auto p = Parser(l); 30 31 Document d = p.parseDocument(); 32 const(Document) cd = d; 33 QueryValidator fv = new QueryValidator(d); 34 fv.accept(cd); 35 noCylces(fv.fragmentChildren); 36 allFragmentsReached(fv); 37 SchemaValidator!StarWarsSchema sv = new SchemaValidator!StarWarsSchema(d, 38 graphqld.schema 39 ); 40 sv.accept(cd); 41 DefaultContext con; 42 immutable Json gqld = graphqld.execute(d, Json.emptyObject(), con); 43 } 44 45 @safe unittest { 46 assertNotThrown(test(` 47 query NestedQueryWithFragment { 48 hero { 49 ...NameAndAppearances 50 friends { 51 ...NameAndAppearances 52 friends { 53 ...NameAndAppearances 54 } 55 } 56 } 57 } 58 59 fragment NameAndAppearances on Character { 60 name 61 appearsIn 62 }`)); 63 } 64 65 @safe unittest { 66 assertThrown!FieldDoesNotExist(test(` 67 query HeroSpaceshipQuery { 68 hero { 69 favoriteSpaceship 70 } 71 } 72 `)); 73 } 74 75 @safe unittest { 76 assertThrown!FieldDoesNotExist(test(` 77 query HeroFieldsOnScalarQuery { 78 hero { 79 name { 80 firstCharacterOfName 81 } 82 } 83 } 84 `)); 85 } 86 87 @safe unittest { 88 assertNotThrown(test(` 89 query DroidFieldInFragment { 90 hero { 91 name 92 ...DroidFields 93 } 94 } 95 96 fragment DroidFields on Droid { 97 primaryFunction 98 } 99 `)); 100 } 101 102 @safe unittest { 103 assertNotThrown(test(` 104 query DroidFieldInFragment { 105 hero { 106 name 107 ... on Droid { 108 primaryFunction 109 } 110 } 111 } 112 `)); 113 }