This commit is contained in:
Robert Mosolgo 2018-10-16 11:05:54 -04:00
Родитель 9202cfa395
Коммит 2a661e14df
3 изменённых файлов: 43 добавлений и 77 удалений

Просмотреть файл

@ -1,3 +1,5 @@
source 'https://rubygems.org'
gemspec
gem "graphql", github: "rmosolgo/graphql-ruby", branch: "1.9-dev"
gem "graphql-client", github: "github/graphql-client", branch: "support-1.9-dev"

Просмотреть файл

@ -58,27 +58,6 @@ module GraphQL::Relay::Walker
true
end
# Private: Make a AST of the given type.
#
# klass - The GraphQL::Language::Nodes::AbstractNode subclass
# to create.
# needs_selections: - Boolean. Will this AST be invalid if it doesn't have
# any selections?
#
# Returns a GraphQL::Language::Nodes::AbstractNode subclass instance or nil
# if the created AST was invalid for having no selections.
def make(klass, needs_selections: true)
k_ast = klass.new
yield(k_ast) if block_given?
k_ast.selections.compact!
if k_ast.selections.empty? && needs_selections
nil
else
k_ast
end
end
# Make an inline fragment AST.
#
# type - The GraphQL::ObjectType instance to make the fragment
@ -89,22 +68,24 @@ module GraphQL::Relay::Walker
# Returns a GraphQL::Language::Nodes::InlineFragment instance or nil if the
# created AST was invalid for having no selections.
def inline_fragment_ast(type, with_children: true)
make(GraphQL::Language::Nodes::InlineFragment) do |if_ast|
if_ast.type = make_type_name_node(type.name)
if with_children
type.all_fields.each do |field|
field_type = field.type.unwrap
if node_field?(field) && include?(field_type)
if_ast.selections << node_field_ast(field)
elsif connection_field?(field) && include?(field_type)
if_ast.selections << connection_field_ast(field)
end
selections = []
if with_children
type.all_fields.each do |field|
field_type = field.type.unwrap
if node_field?(field) && include?(field_type)
selections << node_field_ast(field)
elsif connection_field?(field) && include?(field_type)
selections << connection_field_ast(field)
end
elsif id = type.get_field('id')
if_ast.selections << field_ast(id)
end
elsif id = type.get_field('id')
selections << field_ast(id)
end
GraphQL::Language::Nodes::InlineFragment.new(
type: make_type_name_node(type.name),
selections: selections,
)
end
# Make a field AST.
@ -126,15 +107,12 @@ module GraphQL::Relay::Walker
arguments.key?(name)
end
make(GraphQL::Language::Nodes::Field, needs_selections: !type.kind.scalar?) do |f_ast|
f_ast.name = field.name
f_ast.alias = random_alias unless field.name == 'id'
f_ast.arguments = arguments.map do |name, value|
GraphQL::Language::Nodes::Argument.new(name: name, value: value)
end
yield(f_ast, type) if blk
f_alias = field.name == 'id' ? nil : random_alias
f_args = arguments.map do |name, value|
GraphQL::Language::Nodes::Argument.new(name: name, value: value)
end
GraphQL::Language::Nodes::Field.new(name: field.name, alias: f_alias, arguments: f_args)
end
# Make a field AST for a node field.
@ -143,17 +121,19 @@ module GraphQL::Relay::Walker
#
# Returns a GraphQL::Language::Nodes::Field instance.
def node_field_ast(field)
field_ast(field) do |f_ast, type|
selections = f_ast.selections
f_ast = field_ast(field)
type = field.type.unwrap
selections = f_ast.selections
if type.kind.object?
selections << field_ast(type.get_field('id'))
else
possible_node_types(type).each do |if_type|
selections << inline_fragment_ast(if_type, with_children: false)
end
if type.kind.object?
selections << field_ast(type.get_field('id'))
else
possible_node_types(type).each do |if_type|
selections << inline_fragment_ast(if_type, with_children: false)
end
end
f_ast = f_ast.merge(selections: selections)
f_ast
end
# Make a field AST for an edges field.
@ -162,9 +142,10 @@ module GraphQL::Relay::Walker
#
# Returns a GraphQL::Language::Nodes::Field instance.
def edges_field_ast(field)
field_ast(field) do |f_ast, type|
f_ast.selections << node_field_ast(type.get_field('node'))
end
f_ast = field_ast(field)
node_fields = [node_field_ast(field.type.unwrap.get_field('node'))]
f_ast = f_ast.merge(selections: f_ast.selections + node_fields)
f_ast
end
# Make a field AST for a connection field.
@ -174,9 +155,10 @@ module GraphQL::Relay::Walker
# Returns a GraphQL::Language::Nodes::Field instance or nil if the created
# AST was invalid for missing required arguments.
def connection_field_ast(field)
field_ast(field, connection_arguments) do |f_ast, type|
f_ast.selections << edges_field_ast(type.get_field('edges'))
end
f_ast = field_ast(field, connection_arguments)
edges_fields = [edges_field_ast(field.type.unwrap.get_field('edges'))]
f_ast = f_ast.merge(selections: f_ast.selections + edges_fields)
f_ast
end
# Is this field for a relay node?

Просмотреть файл

@ -30,29 +30,11 @@ describe GraphQL::Relay::Walker::QueryBuilder do
end
describe 'with aliases removed' do
before do
fields(ast).each { |field| field.alias = nil }
end
it 'matches the expected query string' do
expect(subject).to eq(File.read(query_path).strip)
# Replace the aliases, leaving the leading whitespace in place
string_without_aliases = subject.gsub(/ [a-z]{12}: /, " ")
expect(string_without_aliases).to eq(File.read(query_path).strip)
end
end
end
def fields(ast)
nodes(ast).select { |node| node.is_a?(GraphQL::Language::Nodes::Field) }
end
def nodes(ast)
children = if ast.respond_to?(:selections)
ast.selections
elsif ast.respond_to?(:definitions)
ast.definitions
else
[]
end
children + children.map { |child| nodes(child) }.flatten
end
end