graphql 0.19.3 → 0.19.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/graphql/analysis/max_query_complexity.rb +1 -1
- data/lib/graphql/analysis/max_query_depth.rb +1 -1
- data/lib/graphql/boolean_type.rb +2 -2
- data/lib/graphql/define/instance_definable.rb +2 -2
- data/lib/graphql/enum_type.rb +3 -3
- data/lib/graphql/field.rb +6 -6
- data/lib/graphql/float_type.rb +2 -2
- data/lib/graphql/id_type.rb +2 -2
- data/lib/graphql/input_object_type.rb +1 -1
- data/lib/graphql/int_type.rb +2 -2
- data/lib/graphql/internal_representation/rewrite.rb +12 -12
- data/lib/graphql/introspection/arguments_field.rb +1 -1
- data/lib/graphql/introspection/enum_value_type.rb +1 -1
- data/lib/graphql/introspection/enum_values_field.rb +1 -1
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/fields_field.rb +1 -1
- data/lib/graphql/introspection/input_fields_field.rb +1 -1
- data/lib/graphql/introspection/input_value_type.rb +2 -2
- data/lib/graphql/introspection/interfaces_field.rb +1 -1
- data/lib/graphql/introspection/of_type_field.rb +1 -1
- data/lib/graphql/introspection/possible_types_field.rb +1 -1
- data/lib/graphql/introspection/schema_field.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +5 -5
- data/lib/graphql/introspection/type_by_name_field.rb +1 -1
- data/lib/graphql/introspection/type_type.rb +6 -6
- data/lib/graphql/introspection/typename_field.rb +1 -1
- data/lib/graphql/language.rb +1 -0
- data/lib/graphql/language/comments.rb +44 -0
- data/lib/graphql/language/definition_slice.rb +1 -1
- data/lib/graphql/language/generation.rb +35 -12
- data/lib/graphql/language/lexer.rb +29 -10
- data/lib/graphql/language/lexer.rl +25 -6
- data/lib/graphql/language/nodes.rb +30 -23
- data/lib/graphql/language/parser.rb +33 -14
- data/lib/graphql/language/parser.y +33 -14
- data/lib/graphql/language/parser_tests.rb +86 -2
- data/lib/graphql/language/token.rb +3 -2
- data/lib/graphql/language/visitor.rb +3 -3
- data/lib/graphql/object_type.rb +1 -1
- data/lib/graphql/query/arguments.rb +23 -2
- data/lib/graphql/query/serial_execution/field_resolution.rb +31 -14
- data/lib/graphql/relay/base_connection.rb +1 -3
- data/lib/graphql/relay/connection_type.rb +1 -1
- data/lib/graphql/relay/mutation.rb +1 -1
- data/lib/graphql/relay/relation_connection.rb +7 -3
- data/lib/graphql/scalar_type.rb +1 -1
- data/lib/graphql/schema.rb +19 -8
- data/lib/graphql/schema/loader.rb +2 -2
- data/lib/graphql/schema/printer.rb +63 -8
- data/lib/graphql/schema/timeout_middleware.rb +11 -11
- data/lib/graphql/schema/validation.rb +12 -12
- data/lib/graphql/static_validation/arguments_validator.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +3 -2
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +9 -4
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +3 -3
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +2 -2
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +6 -6
- data/lib/graphql/static_validation/type_stack.rb +2 -2
- data/lib/graphql/string_type.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- data/spec/graphql/analysis/analyze_query_spec.rb +3 -3
- data/spec/graphql/analysis/query_complexity_spec.rb +7 -7
- data/spec/graphql/introspection/directive_type_spec.rb +2 -2
- data/spec/graphql/introspection/introspection_query_spec.rb +26 -26
- data/spec/graphql/language/generation_spec.rb +137 -53
- data/spec/graphql/language/lexer_spec.rb +22 -0
- data/spec/graphql/language/visitor_spec.rb +6 -6
- data/spec/graphql/query/arguments_spec.rb +45 -1
- data/spec/graphql/query/context_spec.rb +4 -4
- data/spec/graphql/query/executor_spec.rb +1 -1
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -1
- data/spec/graphql/relay/mutation_spec.rb +2 -2
- data/spec/graphql/relay/node_spec.rb +2 -2
- data/spec/graphql/relay/relation_connection_spec.rb +16 -0
- data/spec/graphql/schema/loader_spec.rb +2 -2
- data/spec/graphql/schema/middleware_chain_spec.rb +6 -6
- data/spec/graphql/schema/printer_spec.rb +268 -18
- data/spec/graphql/schema/rescue_middleware_spec.rb +1 -1
- data/spec/graphql/schema/timeout_middleware_spec.rb +2 -2
- data/spec/graphql/schema_spec.rb +2 -2
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +13 -0
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -1
- data/spec/graphql/static_validation/type_stack_spec.rb +1 -1
- data/spec/support/dairy_app.rb +25 -25
- data/spec/support/dairy_data.rb +2 -0
- data/spec/support/star_wars_data.rb +2 -1
- data/spec/support/star_wars_schema.rb +18 -18
- metadata +19 -2
@@ -6,7 +6,7 @@ module GraphQL
|
|
6
6
|
|
7
7
|
def validate(context)
|
8
8
|
visitor = context.visitor
|
9
|
-
visitor[GraphQL::Language::Nodes::Argument] << ->
|
9
|
+
visitor[GraphQL::Language::Nodes::Argument] << ->(node, parent) {
|
10
10
|
if parent.is_a?(GraphQL::Language::Nodes::InputObject)
|
11
11
|
arg_defn = context.argument_definition
|
12
12
|
if arg_defn.nil?
|
@@ -5,7 +5,7 @@ module GraphQL
|
|
5
5
|
|
6
6
|
def validate(context)
|
7
7
|
directive_names = context.schema.directives.keys
|
8
|
-
context.visitor[GraphQL::Language::Nodes::Directive] << ->
|
8
|
+
context.visitor[GraphQL::Language::Nodes::Directive] << ->(node, parent) {
|
9
9
|
validate_directive(node, directive_names, context)
|
10
10
|
}
|
11
11
|
end
|
@@ -7,7 +7,7 @@ module GraphQL
|
|
7
7
|
def validate(context)
|
8
8
|
directives = context.schema.directives
|
9
9
|
|
10
|
-
context.visitor[Nodes::Directive] << ->
|
10
|
+
context.visitor[Nodes::Directive] << ->(node, parent) {
|
11
11
|
validate_location(node, parent, directives, context)
|
12
12
|
}
|
13
13
|
end
|
@@ -5,7 +5,7 @@ module GraphQL
|
|
5
5
|
|
6
6
|
def validate(context)
|
7
7
|
visitor = context.visitor
|
8
|
-
visitor[GraphQL::Language::Nodes::Field] << ->
|
8
|
+
visitor[GraphQL::Language::Nodes::Field] << ->(node, parent) {
|
9
9
|
return if context.skip_field?(node.name)
|
10
10
|
parent_type = context.object_types[-2]
|
11
11
|
parent_type = parent_type.unwrap
|
@@ -6,7 +6,7 @@ module GraphQL
|
|
6
6
|
include GraphQL::StaticValidation::Message::MessageHelper
|
7
7
|
|
8
8
|
def validate(context)
|
9
|
-
context.visitor[GraphQL::Language::Nodes::Field] << ->
|
9
|
+
context.visitor[GraphQL::Language::Nodes::Field] << ->(node, parent) {
|
10
10
|
return if context.skip_field?(node.name)
|
11
11
|
field_defn = context.field_definition
|
12
12
|
validate_field_selections(node, field_defn, context)
|
@@ -5,12 +5,12 @@ module GraphQL
|
|
5
5
|
fragments = {}
|
6
6
|
has_selections = []
|
7
7
|
visitor = context.visitor
|
8
|
-
visitor[GraphQL::Language::Nodes::OperationDefinition] << ->
|
8
|
+
visitor[GraphQL::Language::Nodes::OperationDefinition] << ->(node, parent) {
|
9
9
|
if node.selections.any?
|
10
10
|
has_selections << node
|
11
11
|
end
|
12
12
|
}
|
13
|
-
visitor[GraphQL::Language::Nodes::Document].leave << ->
|
13
|
+
visitor[GraphQL::Language::Nodes::Document].leave << ->(node, parent) {
|
14
14
|
has_selections.each { |node|
|
15
15
|
field_map = gather_fields_by_name(node.selections, {}, [], context)
|
16
16
|
find_conflicts(field_map, [], context)
|
@@ -92,6 +92,7 @@ module GraphQL
|
|
92
92
|
JSON.dump(arg)
|
93
93
|
end
|
94
94
|
end
|
95
|
+
|
95
96
|
# Turn AST tree into a hash
|
96
97
|
# can't look up args, the names just have to match
|
97
98
|
def reduce_list(args)
|
@@ -5,7 +5,7 @@ module GraphQL
|
|
5
5
|
|
6
6
|
def validate(context)
|
7
7
|
|
8
|
-
context.visitor[GraphQL::Language::Nodes::InlineFragment] << ->
|
8
|
+
context.visitor[GraphQL::Language::Nodes::InlineFragment] << ->(node, parent) {
|
9
9
|
fragment_parent = context.object_types[-2]
|
10
10
|
fragment_child = context.object_types.last
|
11
11
|
if fragment_child
|
@@ -15,12 +15,12 @@ module GraphQL
|
|
15
15
|
|
16
16
|
spreads_to_validate = []
|
17
17
|
|
18
|
-
context.visitor[GraphQL::Language::Nodes::FragmentSpread] << ->
|
18
|
+
context.visitor[GraphQL::Language::Nodes::FragmentSpread] << ->(node, parent) {
|
19
19
|
fragment_parent = context.object_types.last
|
20
20
|
spreads_to_validate << FragmentSpread.new(node: node, parent_type: fragment_parent, path: context.path)
|
21
21
|
}
|
22
22
|
|
23
|
-
context.visitor[GraphQL::Language::Nodes::Document].leave << ->
|
23
|
+
context.visitor[GraphQL::Language::Nodes::Document].leave << ->(doc_node, parent) {
|
24
24
|
spreads_to_validate.each do |frag_spread|
|
25
25
|
fragment_child_name = context.fragments[frag_spread.node.name].type
|
26
26
|
fragment_child = context.schema.types.fetch(fragment_child_name, nil) # Might be non-existent type name
|
@@ -10,7 +10,7 @@ module GraphQL
|
|
10
10
|
|
11
11
|
def validate(context)
|
12
12
|
FRAGMENTS_ON_TYPES.each do |node_class|
|
13
|
-
context.visitor[node_class] << ->
|
13
|
+
context.visitor[node_class] << ->(node, parent) { validate_type_exists(node, context) }
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -4,8 +4,8 @@ module GraphQL
|
|
4
4
|
include GraphQL::StaticValidation::Message::MessageHelper
|
5
5
|
|
6
6
|
def validate(context)
|
7
|
-
context.visitor[GraphQL::Language::Nodes::FragmentDefinition] << ->
|
8
|
-
if has_nested_spread(node, [], context)
|
7
|
+
context.visitor[GraphQL::Language::Nodes::FragmentDefinition] << ->(node, parent) {
|
8
|
+
if has_nested_spread?(node, [], context)
|
9
9
|
context.errors << message("Fragment #{node.name} contains an infinite loop", node, context: context)
|
10
10
|
end
|
11
11
|
}
|
@@ -13,12 +13,17 @@ module GraphQL
|
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
-
def has_nested_spread(fragment_def, parent_fragment_names, context)
|
16
|
+
def has_nested_spread?(fragment_def, parent_fragment_names, context)
|
17
17
|
nested_spreads = get_spreads(fragment_def.selections)
|
18
18
|
|
19
19
|
nested_spreads.any? do |spread|
|
20
20
|
nested_def = context.fragments[spread.name]
|
21
|
-
|
21
|
+
if nested_def.nil?
|
22
|
+
# this is another kind of error
|
23
|
+
false
|
24
|
+
else
|
25
|
+
parent_fragment_names.include?(spread.name) || has_nested_spread?(nested_def, parent_fragment_names + [fragment_def.name], context)
|
26
|
+
end
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
@@ -4,7 +4,7 @@ module GraphQL
|
|
4
4
|
include GraphQL::StaticValidation::Message::MessageHelper
|
5
5
|
|
6
6
|
def validate(context)
|
7
|
-
context.visitor[GraphQL::Language::Nodes::FragmentDefinition] << ->
|
7
|
+
context.visitor[GraphQL::Language::Nodes::FragmentDefinition] << ->(node, parent) { validate_name_exists(node, context) }
|
8
8
|
end
|
9
9
|
|
10
10
|
private
|
@@ -8,19 +8,19 @@ module GraphQL
|
|
8
8
|
used_fragments = []
|
9
9
|
defined_fragments = []
|
10
10
|
|
11
|
-
v[GraphQL::Language::Nodes::Document] << ->
|
11
|
+
v[GraphQL::Language::Nodes::Document] << ->(node, parent) {
|
12
12
|
defined_fragments = node.definitions
|
13
13
|
.select { |defn| defn.is_a?(GraphQL::Language::Nodes::FragmentDefinition) }
|
14
14
|
.map { |node| FragmentInstance.new(node: node, path: context.path) }
|
15
15
|
}
|
16
16
|
|
17
|
-
v[GraphQL::Language::Nodes::FragmentSpread] << ->
|
17
|
+
v[GraphQL::Language::Nodes::FragmentSpread] << ->(node, parent) {
|
18
18
|
used_fragments << FragmentInstance.new(node: node, path: context.path)
|
19
19
|
if defined_fragments.none? { |defn| defn.name == node.name }
|
20
20
|
GraphQL::Language::Visitor::SKIP
|
21
21
|
end
|
22
22
|
}
|
23
|
-
v[GraphQL::Language::Nodes::Document].leave << ->
|
23
|
+
v[GraphQL::Language::Nodes::Document].leave << ->(node, parent) { add_errors(context, used_fragments, defined_fragments) }
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
@@ -8,7 +8,7 @@ module GraphQL
|
|
8
8
|
|
9
9
|
visitor = context.visitor
|
10
10
|
|
11
|
-
visitor[GraphQL::Language::Nodes::OperationDefinition].enter << ->
|
11
|
+
visitor[GraphQL::Language::Nodes::OperationDefinition].enter << ->(ast_node, prev_ast_node) {
|
12
12
|
if ast_node.operation_type == 'mutation'
|
13
13
|
context.errors << message('Schema is not configured for mutations', ast_node, context: context)
|
14
14
|
return GraphQL::Language::Visitor::SKIP
|
@@ -5,8 +5,8 @@ module GraphQL
|
|
5
5
|
|
6
6
|
def validate(context)
|
7
7
|
v = context.visitor
|
8
|
-
v[GraphQL::Language::Nodes::Field] << ->
|
9
|
-
v[GraphQL::Language::Nodes::Directive] << ->
|
8
|
+
v[GraphQL::Language::Nodes::Field] << ->(node, parent) { validate_field(node, context) }
|
9
|
+
v[GraphQL::Language::Nodes::Directive] << ->(node, parent) { validate_directive(node, context) }
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
@@ -8,7 +8,7 @@ module GraphQL
|
|
8
8
|
|
9
9
|
visitor = context.visitor
|
10
10
|
|
11
|
-
visitor[GraphQL::Language::Nodes::OperationDefinition].enter << ->
|
11
|
+
visitor[GraphQL::Language::Nodes::OperationDefinition].enter << ->(ast_node, prev_ast_node) {
|
12
12
|
if ast_node.operation_type == 'subscription'
|
13
13
|
context.errors << message('Schema is not configured for subscriptions', ast_node, context: context)
|
14
14
|
return GraphQL::Language::Visitor::SKIP
|
@@ -5,7 +5,7 @@ module GraphQL
|
|
5
5
|
|
6
6
|
def validate(context)
|
7
7
|
literal_validator = GraphQL::StaticValidation::LiteralValidator.new
|
8
|
-
context.visitor[GraphQL::Language::Nodes::VariableDefinition] << ->
|
8
|
+
context.visitor[GraphQL::Language::Nodes::VariableDefinition] << ->(node, parent) {
|
9
9
|
if !node.default_value.nil?
|
10
10
|
validate_default_value(node, literal_validator, context)
|
11
11
|
end
|
@@ -7,11 +7,11 @@ module GraphQL
|
|
7
7
|
# holds { name => ast_node } pairs
|
8
8
|
declared_variables = {}
|
9
9
|
|
10
|
-
context.visitor[GraphQL::Language::Nodes::OperationDefinition] << ->
|
10
|
+
context.visitor[GraphQL::Language::Nodes::OperationDefinition] << ->(node, parent) {
|
11
11
|
declared_variables = node.variables.each_with_object({}) { |var, memo| memo[var.name] = var }
|
12
12
|
}
|
13
13
|
|
14
|
-
context.visitor[GraphQL::Language::Nodes::Argument] << ->
|
14
|
+
context.visitor[GraphQL::Language::Nodes::Argument] << ->(node, parent) {
|
15
15
|
return if !node.value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
|
16
16
|
if parent.is_a?(GraphQL::Language::Nodes::Field)
|
17
17
|
arguments = context.field_definition.arguments
|
@@ -4,7 +4,7 @@ module GraphQL
|
|
4
4
|
include GraphQL::StaticValidation::Message::MessageHelper
|
5
5
|
|
6
6
|
def validate(context)
|
7
|
-
context.visitor[GraphQL::Language::Nodes::VariableDefinition] << ->
|
7
|
+
context.visitor[GraphQL::Language::Nodes::VariableDefinition] << ->(node, parent) {
|
8
8
|
validate_is_input_type(node, context)
|
9
9
|
}
|
10
10
|
end
|
@@ -35,19 +35,19 @@ module GraphQL
|
|
35
35
|
|
36
36
|
# OperationDefinitions and FragmentDefinitions
|
37
37
|
# both push themselves onto the context stack (and pop themselves off)
|
38
|
-
push_variable_context_stack = ->
|
38
|
+
push_variable_context_stack = ->(node, parent) {
|
39
39
|
# initialize the hash of vars for this context:
|
40
40
|
variable_usages_for_context[node]
|
41
41
|
variable_context_stack.push(node)
|
42
42
|
}
|
43
43
|
|
44
|
-
pop_variable_context_stack = ->
|
44
|
+
pop_variable_context_stack = ->(node, parent) {
|
45
45
|
variable_context_stack.pop
|
46
46
|
}
|
47
47
|
|
48
48
|
|
49
49
|
context.visitor[GraphQL::Language::Nodes::OperationDefinition] << push_variable_context_stack
|
50
|
-
context.visitor[GraphQL::Language::Nodes::OperationDefinition] << ->
|
50
|
+
context.visitor[GraphQL::Language::Nodes::OperationDefinition] << ->(node, parent) {
|
51
51
|
# mark variables as defined:
|
52
52
|
var_hash = variable_usages_for_context[node]
|
53
53
|
node.variables.each { |var|
|
@@ -64,7 +64,7 @@ module GraphQL
|
|
64
64
|
# For FragmentSpreads:
|
65
65
|
# - find the context on the stack
|
66
66
|
# - mark the context as containing this spread
|
67
|
-
context.visitor[GraphQL::Language::Nodes::FragmentSpread] << ->
|
67
|
+
context.visitor[GraphQL::Language::Nodes::FragmentSpread] << ->(node, parent) {
|
68
68
|
variable_context = variable_context_stack.last
|
69
69
|
spreads_for_context[variable_context] << node.name
|
70
70
|
}
|
@@ -72,7 +72,7 @@ module GraphQL
|
|
72
72
|
# For VariableIdentifiers:
|
73
73
|
# - mark the variable as used
|
74
74
|
# - assign its AST node
|
75
|
-
context.visitor[GraphQL::Language::Nodes::VariableIdentifier] << ->
|
75
|
+
context.visitor[GraphQL::Language::Nodes::VariableIdentifier] << ->(node, parent) {
|
76
76
|
usage_context = variable_context_stack.last
|
77
77
|
declared_variables = variable_usages_for_context[usage_context]
|
78
78
|
usage = declared_variables[node.name]
|
@@ -82,7 +82,7 @@ module GraphQL
|
|
82
82
|
}
|
83
83
|
|
84
84
|
|
85
|
-
context.visitor[GraphQL::Language::Nodes::Document].leave << ->
|
85
|
+
context.visitor[GraphQL::Language::Nodes::Document].leave << ->(node, parent) {
|
86
86
|
fragment_definitions = variable_usages_for_context.select { |key, value| key.is_a?(GraphQL::Language::Nodes::FragmentDefinition) }
|
87
87
|
operation_definitions = variable_usages_for_context.select { |key, value| key.is_a?(GraphQL::Language::Nodes::OperationDefinition) }
|
88
88
|
|
@@ -41,8 +41,8 @@ module GraphQL
|
|
41
41
|
@directive_definitions = []
|
42
42
|
@argument_definitions = []
|
43
43
|
@path = []
|
44
|
-
visitor.enter << ->
|
45
|
-
visitor.leave << ->
|
44
|
+
visitor.enter << ->(node, parent) { PUSH_STRATEGIES[node.class].push(self, node) }
|
45
|
+
visitor.leave << ->(node, parent) { PUSH_STRATEGIES[node.class].pop(self, node) }
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
data/lib/graphql/string_type.rb
CHANGED
@@ -2,6 +2,6 @@ GraphQL::STRING_TYPE = GraphQL::ScalarType.define do
|
|
2
2
|
name "String"
|
3
3
|
description "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text."
|
4
4
|
|
5
|
-
coerce_result ->
|
6
|
-
coerce_input ->
|
5
|
+
coerce_result ->(value) { value.to_s }
|
6
|
+
coerce_input ->(value) { value.is_a?(String) ? value : nil }
|
7
7
|
end
|
data/lib/graphql/version.rb
CHANGED
data/readme.md
CHANGED
@@ -17,7 +17,7 @@ describe GraphQL::Analysis do
|
|
17
17
|
|
18
18
|
describe ".analyze_query" do
|
19
19
|
let(:node_counter) {
|
20
|
-
->
|
20
|
+
->(memo, visit_type, irep_node) {
|
21
21
|
memo ||= Hash.new { |h,k| h[k] = 0 }
|
22
22
|
visit_type == :enter && memo[irep_node.ast_node.class] += 1
|
23
23
|
memo
|
@@ -57,7 +57,7 @@ describe GraphQL::Analysis do
|
|
57
57
|
}
|
58
58
|
}
|
59
59
|
|}
|
60
|
-
let(:variable_accessor) { ->
|
60
|
+
let(:variable_accessor) { ->(memo, visit_type, irep_node) { query.variables["cheeseId"] } }
|
61
61
|
|
62
62
|
before do
|
63
63
|
@previous_query_analyzers = DummySchema.query_analyzers.dup
|
@@ -78,7 +78,7 @@ describe GraphQL::Analysis do
|
|
78
78
|
|
79
79
|
describe "when processing fields" do
|
80
80
|
let(:connection_counter) {
|
81
|
-
->
|
81
|
+
->(memo, visit_type, irep_node) {
|
82
82
|
memo ||= Hash.new { |h,k| h[k] = 0 }
|
83
83
|
if visit_type == :enter
|
84
84
|
if irep_node.ast_node.is_a?(GraphQL::Language::Nodes::Field)
|
@@ -223,12 +223,12 @@ describe GraphQL::Analysis::QueryComplexity do
|
|
223
223
|
single_complexity_type = GraphQL::ObjectType.define do
|
224
224
|
name "SingleComplexity"
|
225
225
|
field :value, types.Int, complexity: 0.1 do
|
226
|
-
resolve ->
|
226
|
+
resolve ->(obj, args, ctx) { obj }
|
227
227
|
end
|
228
228
|
field :complexity, single_complexity_type do
|
229
229
|
argument :value, types.Int
|
230
|
-
complexity ->
|
231
|
-
resolve ->
|
230
|
+
complexity ->(ctx, args, child_complexity) { args[:value] + child_complexity }
|
231
|
+
resolve ->(obj, args, ctx) { args[:value] }
|
232
232
|
end
|
233
233
|
interfaces [complexity_interface]
|
234
234
|
end
|
@@ -236,7 +236,7 @@ describe GraphQL::Analysis::QueryComplexity do
|
|
236
236
|
double_complexity_type = GraphQL::ObjectType.define do
|
237
237
|
name "DoubleComplexity"
|
238
238
|
field :value, types.Int, complexity: 4 do
|
239
|
-
resolve ->
|
239
|
+
resolve ->(obj, args, ctx) { obj }
|
240
240
|
end
|
241
241
|
interfaces [complexity_interface]
|
242
242
|
end
|
@@ -245,13 +245,13 @@ describe GraphQL::Analysis::QueryComplexity do
|
|
245
245
|
name "Query"
|
246
246
|
field :complexity, single_complexity_type do
|
247
247
|
argument :value, types.Int
|
248
|
-
complexity ->
|
249
|
-
resolve ->
|
248
|
+
complexity ->(ctx, args, child_complexity) { args[:value] + child_complexity }
|
249
|
+
resolve ->(obj, args, ctx) { args[:value] }
|
250
250
|
end
|
251
251
|
|
252
252
|
field :innerComplexity, complexity_interface do
|
253
253
|
argument :value, types.Int
|
254
|
-
resolve ->
|
254
|
+
resolve ->(obj, args, ctx) { args[:value] }
|
255
255
|
end
|
256
256
|
end
|
257
257
|
|
@@ -23,7 +23,7 @@ describe GraphQL::Introspection::DirectiveType do
|
|
23
23
|
"__schema" => {
|
24
24
|
"directives" => [
|
25
25
|
{
|
26
|
-
"name" => "
|
26
|
+
"name" => "include",
|
27
27
|
"args" => [
|
28
28
|
{"name"=>"if", "type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Boolean"}}}
|
29
29
|
],
|
@@ -33,7 +33,7 @@ describe GraphQL::Introspection::DirectiveType do
|
|
33
33
|
"onOperation" => false,
|
34
34
|
},
|
35
35
|
{
|
36
|
-
"name" => "
|
36
|
+
"name" => "skip",
|
37
37
|
"args" => [
|
38
38
|
{"name"=>"if", "type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Boolean"}}}
|
39
39
|
],
|
@@ -9,18 +9,18 @@ describe "GraphQL::Introspection::INTROSPECTION_QUERY" do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "handles deeply nested (<= 7) schemas" do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
12
|
+
query_type = GraphQL::ObjectType.define do
|
13
|
+
name "DeepQuery"
|
14
|
+
field :foo do
|
15
|
+
type !GraphQL::ListType.new(
|
16
|
+
of_type: !GraphQL::ListType.new(
|
17
|
+
of_type: !GraphQL::ListType.new(
|
18
|
+
of_type: GraphQL::FLOAT_TYPE
|
19
|
+
)
|
20
|
+
)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
24
|
|
25
25
|
deep_schema = GraphQL::Schema.define do
|
26
26
|
query query_type
|
@@ -31,20 +31,20 @@ describe "GraphQL::Introspection::INTROSPECTION_QUERY" do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it "doesn't handle too deeply nested (< 8) schemas" do
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
34
|
+
query_type = GraphQL::ObjectType.define do
|
35
|
+
name "DeepQuery"
|
36
|
+
field :foo do
|
37
|
+
type !GraphQL::ListType.new(
|
38
|
+
of_type: !GraphQL::ListType.new(
|
39
|
+
of_type: !GraphQL::ListType.new(
|
40
|
+
of_type: !GraphQL::ListType.new(
|
41
|
+
of_type: GraphQL::FLOAT_TYPE
|
42
|
+
)
|
43
|
+
)
|
44
|
+
)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
48
|
|
49
49
|
deep_schema = GraphQL::Schema.define do
|
50
50
|
query query_type
|