@@ -142,7 +142,7 @@ class Schema < GraphQL::Schema
142142 GRAPHQL
143143 }
144144
145- it "finds fields on object types and interface types" do
145+ it "enumerates fields on object types and interface types" do
146146 node_lookahead = query . lookahead . selection ( "node" )
147147 assert_equal [ :id , :name , :latin_name ] , node_lookahead . selections . map ( &:name )
148148 end
@@ -243,9 +243,9 @@ class Schema < GraphQL::Schema
243243
244244 it "finds selections using merging" do
245245 merged_lookahead = query . lookahead . selection ( :find_bird_species ) . selection ( :similar_species )
246- assert merged_lookahead . selects? ( :__typename )
247- assert merged_lookahead . selects? ( :is_waterfowl )
248- assert merged_lookahead . selects? ( :name )
246+ assert_equal true , merged_lookahead . selects? ( :__typename )
247+ assert_equal true , merged_lookahead . selects? ( :is_waterfowl )
248+ assert_equal true , merged_lookahead . selects? ( :name )
249249 end
250250 end
251251 end
@@ -279,7 +279,7 @@ class Schema < GraphQL::Schema
279279 it "works for invalid queries" do
280280 context = { lookahead_latin_name : 0 }
281281 res = LookaheadTest ::Schema . execute ( "{ doesNotExist }" , context : context )
282- assert res . key? ( "errors" )
282+ assert_equal true , res . key? ( "errors" )
283283 assert_equal 0 , context [ :lookahead_latin_name ]
284284 end
285285 end
@@ -413,4 +413,185 @@ def query(doc = document)
413413 assert_equal false , lookahead . selects? ( :name )
414414 end
415415 end
416+
417+ describe '#selects?' do
418+ let ( :document ) {
419+ GraphQL . parse <<-GRAPHQL
420+ query {
421+ findBirdSpecies(byName: "Laughing Gull") {
422+ name
423+ similarSpecies {
424+ likesWater: isWaterfowl
425+ }
426+ }
427+ }
428+ GRAPHQL
429+ }
430+
431+ def query ( doc = document )
432+ GraphQL ::Query . new ( LookaheadTest ::Schema , document : doc )
433+ end
434+
435+ it "returns true for each field that is selected" do
436+ ast_node = document . definitions . first . selections . first
437+ field = LookaheadTest ::Query . fields [ "findBirdSpecies" ]
438+ lookahead = GraphQL ::Execution ::Lookahead . new ( query : query , ast_nodes : [ ast_node ] , field : field )
439+ assert_equal true , lookahead . selects? ( :name )
440+ assert_equal true , lookahead . selects? ( :similar_species )
441+ end
442+
443+ it "returns false for a selection which does not match arguments" do
444+ ast_node = document . definitions . first
445+ lookahead = GraphQL ::Execution ::Lookahead . new ( query : query , ast_nodes : [ ast_node ] , root_type : LookaheadTest ::Query )
446+ arguments = { by_name : "Cardinal" }
447+
448+ assert_equal false , lookahead . selects? ( :name , arguments : arguments )
449+ end
450+
451+ it "returns true for a selection which matches arguments" do
452+ ast_node = document . definitions . first
453+ lookahead = GraphQL ::Execution ::Lookahead . new ( query : query , ast_nodes : [ ast_node ] , root_type : LookaheadTest ::Query )
454+ arguments = { by_name : "Laughing Gull" }
455+
456+ assert_equal true , lookahead . selects? ( :find_bird_species , arguments : arguments )
457+ end
458+
459+ it 'returns true for selection that is duplicated across fragments' do
460+ doc = GraphQL . parse <<-GRAPHQL
461+ query {
462+ ... on Query {
463+ ...MoreFields
464+ }
465+ }
466+
467+ fragment MoreFields on Query {
468+ findBirdSpecies(byName: "Laughing Gull") {
469+ name
470+ }
471+ findBirdSpecies(byName: "Laughing Gull") {
472+ ...EvenMoreFields
473+ }
474+ }
475+
476+ fragment EvenMoreFields on BirdSpecies {
477+ similarSpecies {
478+ likesWater: isWaterfowl
479+ }
480+ }
481+ GRAPHQL
482+
483+ lookahead = query ( doc ) . lookahead
484+ assert_equal true , lookahead . selects? ( :find_bird_species )
485+
486+ assert_equal true , lookahead . selection ( :find_bird_species ) . selects? ( :name )
487+ assert_equal true , lookahead . selection ( :find_bird_species ) . selects? ( :similar_species )
488+
489+ # root_selections = lookahead.selections
490+ # assert_equal [:find_bird_species], root_selections.map(&:name), "Selections are merged"
491+ # assert_equal 2, root_selections.first.ast_nodes.size, "It represents both nodes"
492+ #
493+ # assert_equal [:name, :similar_species], root_selections.first.selections.map(&:name), "Subselections are merged"
494+ end
495+
496+ # it "avoids merging selections for same field name on distinct types" do
497+ # query = GraphQL::Query.new(LookaheadTest::Schema, <<-GRAPHQL)
498+ # query {
499+ # node(id: "Cardinal") {
500+ # ... on BirdSpecies {
501+ # name
502+ # }
503+ # ... on BirdGenus {
504+ # name
505+ # }
506+ # id
507+ # }
508+ # }
509+ # GRAPHQL
510+ #
511+ # node_lookahead = query.lookahead.selection("node")
512+ # assert_equal(
513+ # [[LookaheadTest::Node, :id], [LookaheadTest::BirdSpecies, :name], [LookaheadTest::BirdGenus, :name]],
514+ # node_lookahead.selections.map { |s| [s.owner_type, s.name] }
515+ # )
516+ # end
517+
518+ it "works for missing selections" do
519+ ast_node = document . definitions . first . selections . first
520+ field = LookaheadTest ::Query . fields [ "findBirdSpecies" ]
521+ lookahead = GraphQL ::Execution ::Lookahead . new ( query : query , ast_nodes : [ ast_node ] , field : field )
522+ null_lookahead = lookahead . selection ( :genus )
523+ # This is an implementation detail, but I want to make sure the test is set up right
524+ assert_instance_of GraphQL ::Execution ::Lookahead ::NullLookahead , null_lookahead
525+ assert_equal [ ] , null_lookahead . selections
526+ end
527+
528+ it "returns true for fields enabled by directives" do
529+ document = GraphQL . parse <<-GRAPHQL
530+ query($skipName: Boolean!, $includeGenus: Boolean!){
531+ findBirdSpecies(byName: "Cardinal") {
532+ id
533+ name @skip(if: $skipName)
534+ genus @include(if: $includeGenus)
535+ }
536+ }
537+ GRAPHQL
538+ query = GraphQL ::Query . new ( LookaheadTest ::Schema , document : document ,
539+ variables : { skipName : false , includeGenus : true } )
540+ lookahead = query . lookahead . selection ( "findBirdSpecies" )
541+ assert_equal true , lookahead . selects? ( :name )
542+ assert_equal true , lookahead . selects? ( :genus )
543+ end
544+
545+ it "returns false for fields disabled by directive" do
546+ document = GraphQL . parse <<-GRAPHQL
547+ query($skipName: Boolean!, $includeGenus: Boolean!){
548+ findBirdSpecies(byName: "Cardinal") {
549+ id
550+ name @skip(if: $skipName)
551+ genus @include(if: $includeGenus)
552+ }
553+ }
554+ GRAPHQL
555+ query = GraphQL ::Query . new ( LookaheadTest ::Schema , document : document ,
556+ variables : { skipName : true , includeGenus : false } )
557+ lookahead = query . lookahead . selection ( "findBirdSpecies" )
558+ assert_equal true , lookahead . selects? ( :id )
559+ assert_equal false , lookahead . selects? ( :name )
560+ assert_equal false , lookahead . selects? ( :genus )
561+ end
562+
563+ describe "fields on interfaces" do
564+ let ( :document ) {
565+ GraphQL . parse <<-GRAPHQL
566+ query {
567+ node(id: "Cardinal") {
568+ id
569+ ... on BirdSpecies {
570+ name
571+ }
572+ ...Other
573+ }
574+ }
575+ fragment Other on BirdGenus {
576+ latinName
577+ }
578+ GRAPHQL
579+ }
580+
581+ it "returns true for fields on direct object types" do
582+ node_lookahead = query . lookahead . selection ( "node" )
583+ assert_equal true , node_lookahead . selects? ( :id )
584+ end
585+
586+ it "returns true for fields on interface types" do
587+ node_lookahead = query . lookahead . selection ( "node" )
588+ assert_equal true , node_lookahead . selects? ( :name )
589+ end
590+
591+ it "returns true for fields on interface types through fragments" do
592+ node_lookahead = query . lookahead . selection ( "node" )
593+ assert_equal true , node_lookahead . selects? ( :latin_name )
594+ end
595+ end
596+ end
416597end
0 commit comments