Skip to content

Commit 73e41a7

Browse files
Failing specs showing lookahead issue on fragments
1 parent daf2e6a commit 73e41a7

File tree

1 file changed

+186
-5
lines changed

1 file changed

+186
-5
lines changed

spec/graphql/execution/lookahead_spec.rb

Lines changed: 186 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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
416597
end

0 commit comments

Comments
 (0)