Skip to content

Commit

Permalink
Failing specs showing lookahead issue on fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinDaugherty committed Jun 28, 2020
1 parent daf2e6a commit 73e41a7
Showing 1 changed file with 186 additions and 5 deletions.
191 changes: 186 additions & 5 deletions spec/graphql/execution/lookahead_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class Schema < GraphQL::Schema
GRAPHQL
}

it "finds fields on object types and interface types" do
it "enumerates fields on object types and interface types" do
node_lookahead = query.lookahead.selection("node")
assert_equal [:id, :name, :latin_name], node_lookahead.selections.map(&:name)
end
Expand Down Expand Up @@ -243,9 +243,9 @@ class Schema < GraphQL::Schema

it "finds selections using merging" do
merged_lookahead = query.lookahead.selection(:find_bird_species).selection(:similar_species)
assert merged_lookahead.selects?(:__typename)
assert merged_lookahead.selects?(:is_waterfowl)
assert merged_lookahead.selects?(:name)
assert_equal true, merged_lookahead.selects?(:__typename)
assert_equal true, merged_lookahead.selects?(:is_waterfowl)
assert_equal true, merged_lookahead.selects?(:name)
end
end
end
Expand Down Expand Up @@ -279,7 +279,7 @@ class Schema < GraphQL::Schema
it "works for invalid queries" do
context = {lookahead_latin_name: 0}
res = LookaheadTest::Schema.execute("{ doesNotExist }", context: context)
assert res.key?("errors")
assert_equal true, res.key?("errors")
assert_equal 0, context[:lookahead_latin_name]
end
end
Expand Down Expand Up @@ -413,4 +413,185 @@ def query(doc = document)
assert_equal false, lookahead.selects?(:name)
end
end

describe '#selects?' do
let(:document) {
GraphQL.parse <<-GRAPHQL
query {
findBirdSpecies(byName: "Laughing Gull") {
name
similarSpecies {
likesWater: isWaterfowl
}
}
}
GRAPHQL
}

def query(doc = document)
GraphQL::Query.new(LookaheadTest::Schema, document: doc)
end

it "returns true for each field that is selected" do
ast_node = document.definitions.first.selections.first
field = LookaheadTest::Query.fields["findBirdSpecies"]
lookahead = GraphQL::Execution::Lookahead.new(query: query, ast_nodes: [ast_node], field: field)
assert_equal true, lookahead.selects?(:name)
assert_equal true, lookahead.selects?(:similar_species)
end

it "returns false for a selection which does not match arguments" do
ast_node = document.definitions.first
lookahead = GraphQL::Execution::Lookahead.new(query: query, ast_nodes: [ast_node], root_type: LookaheadTest::Query)
arguments = { by_name: "Cardinal" }

assert_equal false, lookahead.selects?(:name, arguments: arguments)
end

it "returns true for a selection which matches arguments" do
ast_node = document.definitions.first
lookahead = GraphQL::Execution::Lookahead.new(query: query, ast_nodes: [ast_node], root_type: LookaheadTest::Query)
arguments = { by_name: "Laughing Gull" }

assert_equal true, lookahead.selects?(:find_bird_species, arguments: arguments)
end

it 'returns true for selection that is duplicated across fragments' do
doc = GraphQL.parse <<-GRAPHQL
query {
... on Query {
...MoreFields
}
}
fragment MoreFields on Query {
findBirdSpecies(byName: "Laughing Gull") {
name
}
findBirdSpecies(byName: "Laughing Gull") {
...EvenMoreFields
}
}
fragment EvenMoreFields on BirdSpecies {
similarSpecies {
likesWater: isWaterfowl
}
}
GRAPHQL

lookahead = query(doc).lookahead
assert_equal true, lookahead.selects?(:find_bird_species)

assert_equal true, lookahead.selection(:find_bird_species).selects?(:name)
assert_equal true, lookahead.selection(:find_bird_species).selects?(:similar_species)

# root_selections = lookahead.selections
# assert_equal [:find_bird_species], root_selections.map(&:name), "Selections are merged"
# assert_equal 2, root_selections.first.ast_nodes.size, "It represents both nodes"
#
# assert_equal [:name, :similar_species], root_selections.first.selections.map(&:name), "Subselections are merged"
end

# it "avoids merging selections for same field name on distinct types" do
# query = GraphQL::Query.new(LookaheadTest::Schema, <<-GRAPHQL)
# query {
# node(id: "Cardinal") {
# ... on BirdSpecies {
# name
# }
# ... on BirdGenus {
# name
# }
# id
# }
# }
# GRAPHQL
#
# node_lookahead = query.lookahead.selection("node")
# assert_equal(
# [[LookaheadTest::Node, :id], [LookaheadTest::BirdSpecies, :name], [LookaheadTest::BirdGenus, :name]],
# node_lookahead.selections.map { |s| [s.owner_type, s.name] }
# )
# end

it "works for missing selections" do
ast_node = document.definitions.first.selections.first
field = LookaheadTest::Query.fields["findBirdSpecies"]
lookahead = GraphQL::Execution::Lookahead.new(query: query, ast_nodes: [ast_node], field: field)
null_lookahead = lookahead.selection(:genus)
# This is an implementation detail, but I want to make sure the test is set up right
assert_instance_of GraphQL::Execution::Lookahead::NullLookahead, null_lookahead
assert_equal [], null_lookahead.selections
end

it "returns true for fields enabled by directives" do
document = GraphQL.parse <<-GRAPHQL
query($skipName: Boolean!, $includeGenus: Boolean!){
findBirdSpecies(byName: "Cardinal") {
id
name @skip(if: $skipName)
genus @include(if: $includeGenus)
}
}
GRAPHQL
query = GraphQL::Query.new(LookaheadTest::Schema, document: document,
variables: { skipName: false, includeGenus: true })
lookahead = query.lookahead.selection("findBirdSpecies")
assert_equal true, lookahead.selects?(:name)
assert_equal true, lookahead.selects?(:genus)
end

it "returns false for fields disabled by directive" do
document = GraphQL.parse <<-GRAPHQL
query($skipName: Boolean!, $includeGenus: Boolean!){
findBirdSpecies(byName: "Cardinal") {
id
name @skip(if: $skipName)
genus @include(if: $includeGenus)
}
}
GRAPHQL
query = GraphQL::Query.new(LookaheadTest::Schema, document: document,
variables: { skipName: true, includeGenus: false })
lookahead = query.lookahead.selection("findBirdSpecies")
assert_equal true, lookahead.selects?(:id)
assert_equal false, lookahead.selects?(:name)
assert_equal false, lookahead.selects?(:genus)
end

describe "fields on interfaces" do
let(:document) {
GraphQL.parse <<-GRAPHQL
query {
node(id: "Cardinal") {
id
... on BirdSpecies {
name
}
...Other
}
}
fragment Other on BirdGenus {
latinName
}
GRAPHQL
}

it "returns true for fields on direct object types" do
node_lookahead = query.lookahead.selection("node")
assert_equal true, node_lookahead.selects?(:id)
end

it "returns true for fields on interface types" do
node_lookahead = query.lookahead.selection("node")
assert_equal true, node_lookahead.selects?(:name)
end

it "returns true for fields on interface types through fragments" do
node_lookahead = query.lookahead.selection("node")
assert_equal true, node_lookahead.selects?(:latin_name)
end
end
end
end

0 comments on commit 73e41a7

Please sign in to comment.