graphql 1.6.4 → 1.6.5
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/generators/graphql/core.rb +47 -0
- data/lib/generators/graphql/install_generator.rb +15 -20
- data/lib/generators/graphql/mutation_generator.rb +31 -1
- data/lib/generators/graphql/templates/mutation.erb +2 -2
- data/lib/generators/graphql/templates/mutation_type.erb +5 -0
- data/lib/generators/graphql/templates/schema.erb +0 -1
- data/lib/graphql/argument.rb +6 -5
- data/lib/graphql/backwards_compatibility.rb +18 -4
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -1
- data/lib/graphql/compatibility/lazy_execution_specification.rb +9 -2
- data/lib/graphql/define.rb +1 -0
- data/lib/graphql/define/defined_object_proxy.rb +1 -1
- data/lib/graphql/define/no_definition_error.rb +7 -0
- data/lib/graphql/enum_type.rb +4 -0
- data/lib/graphql/execution/execute.rb +3 -3
- data/lib/graphql/execution/field_result.rb +1 -1
- data/lib/graphql/execution/lazy/resolve.rb +10 -9
- data/lib/graphql/execution/multiplex.rb +6 -5
- data/lib/graphql/input_object_type.rb +5 -1
- data/lib/graphql/interface_type.rb +12 -3
- data/lib/graphql/query.rb +21 -5
- data/lib/graphql/query/context.rb +11 -0
- data/lib/graphql/schema.rb +48 -27
- data/lib/graphql/schema/build_from_definition.rb +1 -1
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +2 -2
- data/lib/graphql/schema/loader.rb +1 -1
- data/lib/graphql/schema/traversal.rb +91 -0
- data/lib/graphql/schema/validation.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +41 -7
- data/lib/graphql/union_type.rb +13 -2
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -3
- data/spec/generators/graphql/install_generator_spec.rb +3 -1
- data/spec/generators/graphql/mutation_generator_spec.rb +14 -0
- data/spec/graphql/analysis/max_query_complexity_spec.rb +12 -1
- data/spec/graphql/analysis/query_complexity_spec.rb +1 -1
- data/spec/graphql/argument_spec.rb +29 -0
- data/spec/graphql/define/assign_argument_spec.rb +4 -4
- data/spec/graphql/define/instance_definable_spec.rb +1 -1
- data/spec/graphql/enum_type_spec.rb +8 -0
- data/spec/graphql/execution/lazy_spec.rb +30 -3
- data/spec/graphql/interface_type_spec.rb +44 -0
- data/spec/graphql/introspection/schema_type_spec.rb +3 -0
- data/spec/graphql/introspection/type_type_spec.rb +1 -0
- data/spec/graphql/object_type_spec.rb +8 -3
- data/spec/graphql/query/context_spec.rb +18 -0
- data/spec/graphql/query/executor_spec.rb +1 -1
- data/spec/graphql/query/literal_input_spec.rb +31 -15
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -1
- data/spec/graphql/query/variables_spec.rb +25 -1
- data/spec/graphql/query_spec.rb +24 -9
- data/spec/graphql/relay/mutation_spec.rb +1 -1
- data/spec/graphql/schema/build_from_definition_spec.rb +1 -1
- data/spec/graphql/schema/loader_spec.rb +1 -1
- data/spec/graphql/schema/printer_spec.rb +1 -1
- data/spec/graphql/schema/{reduce_types_spec.rb → traversal_spec.rb} +21 -4
- data/spec/graphql/schema/warden_spec.rb +1 -1
- data/spec/graphql/schema_spec.rb +23 -2
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +133 -0
- data/spec/graphql/union_type_spec.rb +53 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/dummy/data.rb +14 -5
- data/spec/support/dummy/schema.rb +46 -5
- data/spec/support/star_wars/data.rb +10 -6
- data/spec/support/star_wars/schema.rb +5 -2
- metadata +8 -7
- data/lib/graphql/schema/instrumented_field_map.rb +0 -40
- data/lib/graphql/schema/reduce_types.rb +0 -69
- data/lib/graphql/schema/type_map.rb +0 -31
| @@ -274,10 +274,10 @@ module GraphQL | |
| 274 274 | 
             
                      Rules::FIELDS_ARE_VALID,
         | 
| 275 275 | 
             
                    ],
         | 
| 276 276 | 
             
                    GraphQL::Schema => [
         | 
| 277 | 
            +
                      Rules::SCHEMA_INSTRUMENTERS_ARE_VALID,
         | 
| 277 278 | 
             
                      Rules::SCHEMA_CAN_RESOLVE_TYPES,
         | 
| 278 279 | 
             
                      Rules::SCHEMA_CAN_FETCH_IDS,
         | 
| 279 280 | 
             
                      Rules::SCHEMA_CAN_GENERATE_IDS,
         | 
| 280 | 
            -
                      Rules::SCHEMA_INSTRUMENTERS_ARE_VALID,
         | 
| 281 281 | 
             
                    ],
         | 
| 282 282 | 
             
                  }
         | 
| 283 283 | 
             
                end
         | 
| @@ -7,15 +7,15 @@ module GraphQL | |
| 7 7 | 
             
                  def validate(context)
         | 
| 8 8 | 
             
                    # holds { name => ast_node } pairs
         | 
| 9 9 | 
             
                    declared_variables = {}
         | 
| 10 | 
            -
             | 
| 11 10 | 
             
                    context.visitor[GraphQL::Language::Nodes::OperationDefinition] << ->(node, parent) {
         | 
| 12 11 | 
             
                      declared_variables = node.variables.each_with_object({}) { |var, memo| memo[var.name] = var }
         | 
| 13 12 | 
             
                    }
         | 
| 14 13 |  | 
| 15 14 | 
             
                    context.visitor[GraphQL::Language::Nodes::Argument] << ->(node, parent) {
         | 
| 16 | 
            -
                       | 
| 17 | 
            -
                       | 
| 15 | 
            +
                      node_values = Array.wrap(node.value).select { |value| value.is_a? GraphQL::Language::Nodes::VariableIdentifier }
         | 
| 16 | 
            +
                      return if node_values.none?
         | 
| 18 17 |  | 
| 18 | 
            +
                      arguments = nil
         | 
| 19 19 | 
             
                      case parent
         | 
| 20 20 | 
             
                      when GraphQL::Language::Nodes::Field
         | 
| 21 21 | 
             
                        arguments = context.field_definition.arguments
         | 
| @@ -29,10 +29,13 @@ module GraphQL | |
| 29 29 | 
             
                      else
         | 
| 30 30 | 
             
                        raise("Unexpected argument parent: #{parent}")
         | 
| 31 31 | 
             
                      end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                       | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 32 | 
            +
             | 
| 33 | 
            +
                      node_values.each do |node_value|
         | 
| 34 | 
            +
                        var_defn_ast = declared_variables[node_value.name]
         | 
| 35 | 
            +
                        # Might be undefined :(
         | 
| 36 | 
            +
                        # VariablesAreUsedAndDefined can't finalize its search until the end of the document.
         | 
| 37 | 
            +
                        var_defn_ast && arguments && validate_usage(arguments, node, var_defn_ast, context)
         | 
| 38 | 
            +
                      end
         | 
| 36 39 | 
             
                    }
         | 
| 37 40 | 
             
                  end
         | 
| 38 41 |  | 
| @@ -53,6 +56,8 @@ module GraphQL | |
| 53 56 | 
             
                    var_inner_type = var_type.unwrap
         | 
| 54 57 | 
             
                    arg_inner_type = arg_defn_type.unwrap
         | 
| 55 58 |  | 
| 59 | 
            +
                    var_type = wrap_var_type_with_depth_of_arg(var_type, arg_node)
         | 
| 60 | 
            +
             | 
| 56 61 | 
             
                    if var_inner_type != arg_inner_type
         | 
| 57 62 | 
             
                      context.errors << create_error("Type mismatch", var_type, ast_var, arg_defn, arg_node, context)
         | 
| 58 63 | 
             
                    elsif list_dimension(var_type) != list_dimension(arg_defn_type)
         | 
| @@ -66,6 +71,35 @@ module GraphQL | |
| 66 71 | 
             
                    message("#{error_message} on variable $#{ast_var.name} and argument #{arg_node.name} (#{var_type.to_s} / #{arg_defn.type.to_s})", arg_node, context: context)
         | 
| 67 72 | 
             
                  end
         | 
| 68 73 |  | 
| 74 | 
            +
                  def wrap_var_type_with_depth_of_arg(var_type, arg_node)
         | 
| 75 | 
            +
                    arg_node_value = arg_node.value
         | 
| 76 | 
            +
                    return var_type unless arg_node_value.is_a?(Array)
         | 
| 77 | 
            +
                    new_var_type = var_type
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                    depth_of_array(arg_node_value).times do
         | 
| 80 | 
            +
                      new_var_type = GraphQL::ListType.new(of_type: new_var_type)
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    new_var_type
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                  # @return [Integer] Returns the max depth of `array`, or `0` if it isn't an array at all
         | 
| 87 | 
            +
                  def depth_of_array(array)
         | 
| 88 | 
            +
                    case array
         | 
| 89 | 
            +
                    when Array
         | 
| 90 | 
            +
                      max_child_depth = 0
         | 
| 91 | 
            +
                      array.each do |item|
         | 
| 92 | 
            +
                        item_depth = depth_of_array(item)
         | 
| 93 | 
            +
                        if item_depth > max_child_depth
         | 
| 94 | 
            +
                          max_child_depth = item_depth
         | 
| 95 | 
            +
                        end
         | 
| 96 | 
            +
                      end
         | 
| 97 | 
            +
                      1 + max_child_depth
         | 
| 98 | 
            +
                    else
         | 
| 99 | 
            +
                      0
         | 
| 100 | 
            +
                    end
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
             | 
| 69 103 | 
             
                  def list_dimension(type)
         | 
| 70 104 | 
             
                    if type.kind.list?
         | 
| 71 105 | 
             
                      1 + list_dimension(type.of_type)
         | 
    
        data/lib/graphql/union_type.rb
    CHANGED
    
    | @@ -24,13 +24,16 @@ module GraphQL | |
| 24 24 | 
             
              #  }
         | 
| 25 25 | 
             
              #
         | 
| 26 26 | 
             
              class UnionType < GraphQL::BaseType
         | 
| 27 | 
            -
                accepts_definitions :possible_types
         | 
| 28 | 
            -
                ensure_defined :possible_types
         | 
| 27 | 
            +
                accepts_definitions :possible_types, :resolve_type
         | 
| 28 | 
            +
                ensure_defined :possible_types, :resolve_type, :resolve_type_proc
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                attr_accessor :resolve_type_proc
         | 
| 29 31 |  | 
| 30 32 | 
             
                def initialize
         | 
| 31 33 | 
             
                  super
         | 
| 32 34 | 
             
                  @dirty_possible_types = []
         | 
| 33 35 | 
             
                  @clean_possible_types = nil
         | 
| 36 | 
            +
                  @resolve_type_proc = nil
         | 
| 34 37 | 
             
                end
         | 
| 35 38 |  | 
| 36 39 | 
             
                def initialize_copy(other)
         | 
| @@ -64,6 +67,14 @@ module GraphQL | |
| 64 67 | 
             
                  end
         | 
| 65 68 | 
             
                end
         | 
| 66 69 |  | 
| 70 | 
            +
                def resolve_type(value, ctx)
         | 
| 71 | 
            +
                  ctx.query.resolve_type(self, value)
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def resolve_type=(new_resolve_type_proc)
         | 
| 75 | 
            +
                  @resolve_type_proc = new_resolve_type_proc
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 67 78 | 
             
                protected
         | 
| 68 79 |  | 
| 69 80 | 
             
                attr_reader :dirty_possible_types
         | 
    
        data/lib/graphql/version.rb
    CHANGED
    
    
    
        data/readme.md
    CHANGED
    
    | @@ -49,6 +49,4 @@ I also sell [GraphQL::Pro](http://graphql.pro) which provides several features o | |
| 49 49 |  | 
| 50 50 | 
             
            - __Say hi & ask questions__ in the [#ruby channel on Slack](https://graphql-slack.herokuapp.com/) or [on Twitter](https://twitter.com/rmosolgo)!
         | 
| 51 51 | 
             
            - __Report bugs__ by posting a description, full stack trace, and all relevant code in a  [GitHub issue](https://github.com/rmosolgo/graphql-ruby/issues).
         | 
| 52 | 
            -
            -  | 
| 53 | 
            -
            - __Run the tests__ with `rake test` or start up guard with `bundle exec guard`.
         | 
| 54 | 
            -
            - __Build the site__ with `rake site:serve`, then visit `http://localhost:4000/graphql-ruby/`.
         | 
| 52 | 
            +
            - __Start hacking__ with the [Development guide](http://graphql-ruby.org/development).
         | 
| @@ -37,6 +37,7 @@ class GraphQLGeneratorsInstallGeneratorTest < Rails::Generators::TestCase | |
| 37 37 |  | 
| 38 38 | 
             
                expected_schema = <<-RUBY
         | 
| 39 39 | 
             
            DummySchema = GraphQL::Schema.define do
         | 
| 40 | 
            +
              mutation(Types::MutationType)
         | 
| 40 41 | 
             
              query(Types::QueryType)
         | 
| 41 42 | 
             
            end
         | 
| 42 43 | 
             
            RUBY
         | 
| @@ -160,8 +161,9 @@ RUBY | |
| 160 161 |  | 
| 161 162 | 
             
              EXPECTED_RELAY_BATCH_SCHEMA = <<-RUBY
         | 
| 162 163 | 
             
            DummySchema = GraphQL::Schema.define do
         | 
| 163 | 
            -
              query(Types::QueryType)
         | 
| 164 164 |  | 
| 165 | 
            +
              mutation(Types::MutationType)
         | 
| 166 | 
            +
              query(Types::QueryType)
         | 
| 165 167 | 
             
              # Relay Object Identification:
         | 
| 166 168 |  | 
| 167 169 | 
             
              # Return a string UUID for `object`
         | 
| @@ -5,6 +5,20 @@ require "generators/graphql/mutation_generator" | |
| 5 5 | 
             
            class GraphQLGeneratorsMutationGeneratorTest < BaseGeneratorTest
         | 
| 6 6 | 
             
              tests Graphql::Generators::MutationGenerator
         | 
| 7 7 |  | 
| 8 | 
            +
              destination File.expand_path("../../../tmp/dummy", File.dirname(__FILE__))
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              setup do
         | 
| 11 | 
            +
                prepare_destination
         | 
| 12 | 
            +
                FileUtils.cd(File.expand_path("../../../tmp", File.dirname(__FILE__))) do
         | 
| 13 | 
            +
                  `rm -rf dummy`
         | 
| 14 | 
            +
                  `rails new dummy --skip-active-record --skip-test-unit --skip-spring --skip-bundle`
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                FileUtils.cd(destination_root) do
         | 
| 18 | 
            +
                  `rails g graphql:install`
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 8 22 | 
             
              test "it generates an empty resolver by name" do
         | 
| 9 23 | 
             
                run_generator(["UpdateName"])
         | 
| 10 24 |  | 
| @@ -50,7 +50,7 @@ describe GraphQL::Analysis::MaxQueryComplexity do | |
| 50 50 | 
             
                end
         | 
| 51 51 | 
             
              end
         | 
| 52 52 |  | 
| 53 | 
            -
              describe "when  | 
| 53 | 
            +
              describe "when max_complexity is decreased at query-level" do
         | 
| 54 54 | 
             
                before do
         | 
| 55 55 | 
             
                  Dummy::Schema.max_complexity = 100
         | 
| 56 56 | 
             
                end
         | 
| @@ -61,6 +61,17 @@ describe GraphQL::Analysis::MaxQueryComplexity do | |
| 61 61 | 
             
                end
         | 
| 62 62 | 
             
              end
         | 
| 63 63 |  | 
| 64 | 
            +
              describe "when max_complexity is increased at query-level" do
         | 
| 65 | 
            +
                before do
         | 
| 66 | 
            +
                  Dummy::Schema.max_complexity = 1
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
                let(:result) { Dummy::Schema.execute(query_string, max_complexity: 10) }
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                it "doesn't error" do
         | 
| 71 | 
            +
                  assert_equal nil, result["errors"]
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 64 75 | 
             
              describe "across a multiplex" do
         | 
| 65 76 | 
             
                before do
         | 
| 66 77 | 
             
                  Dummy::Schema.max_complexity = 9
         | 
| @@ -19,6 +19,18 @@ describe GraphQL::Argument do | |
| 19 19 | 
             
                assert_includes err.message, expected_error
         | 
| 20 20 | 
             
              end
         | 
| 21 21 |  | 
| 22 | 
            +
              it "accepts custom keywords" do
         | 
| 23 | 
            +
                type = GraphQL::ObjectType.define do
         | 
| 24 | 
            +
                  name "Something"
         | 
| 25 | 
            +
                  field :something, types.String do
         | 
| 26 | 
            +
                    argument "flagged", types.Int, metadata_flag: :flag_1
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                arg = type.fields["something"].arguments["flagged"]
         | 
| 31 | 
            +
                assert_equal true, arg.metadata[:flag_1]
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 22 34 | 
             
              it "accepts proc type" do
         | 
| 23 35 | 
             
                argument = GraphQL::Argument.define(name: :favoriteFood, type: -> { GraphQL::STRING_TYPE })
         | 
| 24 36 | 
             
                assert_equal GraphQL::STRING_TYPE, argument.type
         | 
| @@ -56,6 +68,14 @@ describe GraphQL::Argument do | |
| 56 68 | 
             
                  arg_3 = arg_2.redefine { as :ff }
         | 
| 57 69 | 
             
                  assert_equal arg_3.expose_as, "ff"
         | 
| 58 70 | 
             
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                it "can be set in the passed block" do
         | 
| 73 | 
            +
                  argument = GraphQL::Argument.define do
         | 
| 74 | 
            +
                    name "arg"
         | 
| 75 | 
            +
                    as "arg_name"
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                  assert_equal "arg_name", argument.as
         | 
| 78 | 
            +
                end
         | 
| 59 79 | 
             
              end
         | 
| 60 80 |  | 
| 61 81 | 
             
              describe "prepare" do
         | 
| @@ -69,5 +89,14 @@ describe GraphQL::Argument do | |
| 69 89 | 
             
                  argument = GraphQL::Argument.define(name: :someNumber, type: GraphQL::INT_TYPE)
         | 
| 70 90 | 
             
                  assert_equal argument.prepare(1, nil), 1
         | 
| 71 91 | 
             
                end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                it "can be set in the passed block" do
         | 
| 94 | 
            +
                  prepare_proc = Proc.new { |arg, ctx| arg + ctx[:val] }
         | 
| 95 | 
            +
                  argument = GraphQL::Argument.define do
         | 
| 96 | 
            +
                    name "arg"
         | 
| 97 | 
            +
                    prepare prepare_proc
         | 
| 98 | 
            +
                  end
         | 
| 99 | 
            +
                  assert_equal argument.prepare(1, {val: 1}), 2
         | 
| 100 | 
            +
                end
         | 
| 72 101 | 
             
              end
         | 
| 73 102 | 
             
            end
         | 
| @@ -24,17 +24,17 @@ describe GraphQL::Define::AssignArgument do | |
| 24 24 | 
             
              end
         | 
| 25 25 |  | 
| 26 26 | 
             
              it "passing unknown keyword arguments will raise" do
         | 
| 27 | 
            -
                err = assert_raises  | 
| 27 | 
            +
                err = assert_raises GraphQL::Define::NoDefinitionError do
         | 
| 28 28 | 
             
                  define_argument(:a, GraphQL::STRING_TYPE, blah: nil)
         | 
| 29 29 | 
             
                end
         | 
| 30 30 |  | 
| 31 | 
            -
                assert_equal ' | 
| 31 | 
            +
                assert_equal "GraphQL::Argument can't define 'blah'", err.message
         | 
| 32 32 |  | 
| 33 | 
            -
                err = assert_raises  | 
| 33 | 
            +
                err = assert_raises GraphQL::Define::NoDefinitionError do
         | 
| 34 34 | 
             
                  define_argument(:a, GraphQL::STRING_TYPE, blah: nil, blah2: nil)
         | 
| 35 35 | 
             
                end
         | 
| 36 36 |  | 
| 37 | 
            -
                assert_equal ' | 
| 37 | 
            +
                assert_equal "GraphQL::Argument can't define 'blah'", err.message
         | 
| 38 38 | 
             
              end
         | 
| 39 39 |  | 
| 40 40 | 
             
              def define_argument(*args)
         | 
| @@ -185,7 +185,7 @@ describe GraphQL::Define::InstanceDefinable do | |
| 185 185 |  | 
| 186 186 | 
             
              describe "typos" do
         | 
| 187 187 | 
             
                it "provides the right class name, method name and line number" do
         | 
| 188 | 
            -
                  err = assert_raises( | 
| 188 | 
            +
                  err = assert_raises(GraphQL::Define::NoDefinitionError) {
         | 
| 189 189 | 
             
                    beet = Garden::Vegetable.define {
         | 
| 190 190 | 
             
                      name "Beet"
         | 
| 191 191 | 
             
                      nonsense :Blah
         | 
| @@ -110,4 +110,12 @@ describe GraphQL::EnumType do | |
| 110 110 | 
             
                  assert_equal(7, enum_2.values.size)
         | 
| 111 111 | 
             
                end
         | 
| 112 112 | 
             
              end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
              describe "validates enum value name uniqueness" do
         | 
| 115 | 
            +
                it "raises an exception when adding a duplicate enum value name" do
         | 
| 116 | 
            +
                  assert_raises "Enum value names must be unique. `COW` already exists." do
         | 
| 117 | 
            +
                    enum.add_value(GraphQL::EnumType::EnumValue.define(name: "COW"))
         | 
| 118 | 
            +
                  end
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
              end
         | 
| 113 121 | 
             
            end
         | 
| @@ -17,12 +17,24 @@ describe GraphQL::Execution::Lazy do | |
| 17 17 | 
             
                      value
         | 
| 18 18 | 
             
                      nestedSum(value: 7) {
         | 
| 19 19 | 
             
                        value
         | 
| 20 | 
            +
                        nestedSum(value: 1) {
         | 
| 21 | 
            +
                          value
         | 
| 22 | 
            +
                          nestedSum(value: -50) {
         | 
| 23 | 
            +
                            value
         | 
| 24 | 
            +
                          }
         | 
| 25 | 
            +
                        }
         | 
| 20 26 | 
             
                      }
         | 
| 21 27 | 
             
                    }
         | 
| 22 28 | 
             
                    b: nestedSum(value: 2) {
         | 
| 23 29 | 
             
                      value
         | 
| 24 30 | 
             
                      nestedSum(value: 11) {
         | 
| 25 31 | 
             
                        value
         | 
| 32 | 
            +
                        nestedSum(value: 2) {
         | 
| 33 | 
            +
                          value
         | 
| 34 | 
            +
                          nestedSum(value: -50) {
         | 
| 35 | 
            +
                            value
         | 
| 36 | 
            +
                          }
         | 
| 37 | 
            +
                        }
         | 
| 26 38 | 
             
                      }
         | 
| 27 39 | 
             
                    }
         | 
| 28 40 |  | 
| @@ -35,9 +47,24 @@ describe GraphQL::Execution::Lazy do | |
| 35 47 | 
             
                  |
         | 
| 36 48 |  | 
| 37 49 | 
             
                  expected_data = {
         | 
| 38 | 
            -
                    "a"=>{"value"=>14, "nestedSum"=>{ | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 50 | 
            +
                    "a"=>{"value"=>14, "nestedSum"=>{
         | 
| 51 | 
            +
                      "value"=>46,
         | 
| 52 | 
            +
                      "nestedSum"=>{
         | 
| 53 | 
            +
                        "value"=>95,
         | 
| 54 | 
            +
                        "nestedSum"=>{"value"=>90}
         | 
| 55 | 
            +
                      }
         | 
| 56 | 
            +
                    }},
         | 
| 57 | 
            +
                    "b"=>{"value"=>14, "nestedSum"=>{
         | 
| 58 | 
            +
                      "value"=>46,
         | 
| 59 | 
            +
                      "nestedSum"=>{
         | 
| 60 | 
            +
                        "value"=>95,
         | 
| 61 | 
            +
                        "nestedSum"=>{"value"=>90}
         | 
| 62 | 
            +
                      }
         | 
| 63 | 
            +
                    }},
         | 
| 64 | 
            +
                    "c"=>[
         | 
| 65 | 
            +
                      {"nestedSum"=>{"value"=>14}},
         | 
| 66 | 
            +
                      {"nestedSum"=>{"value"=>14}}
         | 
| 67 | 
            +
                    ],
         | 
| 41 68 | 
             
                  }
         | 
| 42 69 |  | 
| 43 70 | 
             
                  assert_equal expected_data, res["data"]
         | 
| @@ -93,4 +93,48 @@ describe GraphQL::InterfaceType do | |
| 93 93 | 
             
                  assert_equal 4, interface_2.fields.size
         | 
| 94 94 | 
             
                end
         | 
| 95 95 | 
             
              end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
              describe "#resolve_type" do
         | 
| 98 | 
            +
                let(:result) { Dummy::Schema.execute(query_string) }
         | 
| 99 | 
            +
                let(:query_string) {%|
         | 
| 100 | 
            +
                  {
         | 
| 101 | 
            +
                    allEdible {
         | 
| 102 | 
            +
                      __typename
         | 
| 103 | 
            +
                      ... on Milk {
         | 
| 104 | 
            +
                        milkFatContent: fatContent
         | 
| 105 | 
            +
                      }
         | 
| 106 | 
            +
                      ... on Cheese {
         | 
| 107 | 
            +
                        cheeseFatContent: fatContent
         | 
| 108 | 
            +
                      }
         | 
| 109 | 
            +
                    }
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                    allEdibleAsMilk {
         | 
| 112 | 
            +
                      __typename
         | 
| 113 | 
            +
                      ... on Milk {
         | 
| 114 | 
            +
                        fatContent
         | 
| 115 | 
            +
                      }
         | 
| 116 | 
            +
                    }
         | 
| 117 | 
            +
                  }
         | 
| 118 | 
            +
                |}
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                it 'returns correct types for general schema and specific interface' do
         | 
| 121 | 
            +
                  expected_result = {
         | 
| 122 | 
            +
                    # Uses schema-level resolve_type
         | 
| 123 | 
            +
                    "allEdible"=>[
         | 
| 124 | 
            +
                      {"__typename"=>"Cheese", "cheeseFatContent"=>0.19},
         | 
| 125 | 
            +
                      {"__typename"=>"Cheese", "cheeseFatContent"=>0.3},
         | 
| 126 | 
            +
                      {"__typename"=>"Cheese", "cheeseFatContent"=>0.065},
         | 
| 127 | 
            +
                      {"__typename"=>"Milk", "milkFatContent"=>0.04}
         | 
| 128 | 
            +
                    ],
         | 
| 129 | 
            +
                    # Uses type-level resolve_type
         | 
| 130 | 
            +
                    "allEdibleAsMilk"=>[
         | 
| 131 | 
            +
                      {"__typename"=>"Milk", "fatContent"=>0.19},
         | 
| 132 | 
            +
                      {"__typename"=>"Milk", "fatContent"=>0.3},
         | 
| 133 | 
            +
                      {"__typename"=>"Milk", "fatContent"=>0.065},
         | 
| 134 | 
            +
                      {"__typename"=>"Milk", "fatContent"=>0.04}
         | 
| 135 | 
            +
                    ]
         | 
| 136 | 
            +
                  }
         | 
| 137 | 
            +
                  assert_equal expected_result, result["data"]
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
              end
         | 
| 96 140 | 
             
            end
         | 
| @@ -19,8 +19,11 @@ describe GraphQL::Introspection::SchemaType do | |
| 19 19 | 
             
                    "types" => Dummy::Schema.types.values.map { |t| t.name.nil? ? (p t; raise("no name for #{t}")) : {"name" => t.name} },
         | 
| 20 20 | 
             
                    "queryType"=>{
         | 
| 21 21 | 
             
                      "fields"=>[
         | 
| 22 | 
            +
                        {"name"=>"allAnimal"},
         | 
| 23 | 
            +
                        {"name"=>"allAnimalAsCow"},
         | 
| 22 24 | 
             
                        {"name"=>"allDairy"},
         | 
| 23 25 | 
             
                        {"name"=>"allEdible"},
         | 
| 26 | 
            +
                        {"name"=>"allEdibleAsMilk"},
         | 
| 24 27 | 
             
                        {"name"=>"cheese"},
         | 
| 25 28 | 
             
                        {"name"=>"cow"},
         | 
| 26 29 | 
             
                        {"name"=>"dairy"},
         | 
| @@ -17,7 +17,12 @@ describe GraphQL::ObjectType do | |
| 17 17 |  | 
| 18 18 | 
             
              describe "interfaces" do
         | 
| 19 19 | 
             
                it "may have interfaces" do
         | 
| 20 | 
            -
                  assert_equal([ | 
| 20 | 
            +
                  assert_equal([
         | 
| 21 | 
            +
                    Dummy::EdibleInterface,
         | 
| 22 | 
            +
                    Dummy::EdibleAsMilkInterface,
         | 
| 23 | 
            +
                    Dummy::AnimalProductInterface,
         | 
| 24 | 
            +
                    Dummy::LocalProductInterface
         | 
| 25 | 
            +
                  ], type.interfaces)
         | 
| 21 26 | 
             
                end
         | 
| 22 27 |  | 
| 23 28 | 
             
                it "raises if the interfaces arent an array" do
         | 
| @@ -129,8 +134,8 @@ describe GraphQL::ObjectType do | |
| 129 134 |  | 
| 130 135 | 
             
                  type_2.fields["nonsense"] = GraphQL::Field.define(name: "nonsense", type: type)
         | 
| 131 136 |  | 
| 132 | 
            -
                  assert_equal  | 
| 133 | 
            -
                  assert_equal  | 
| 137 | 
            +
                  assert_equal 4, type.interfaces.size
         | 
| 138 | 
            +
                  assert_equal 5, type_2.interfaces.size
         | 
| 134 139 | 
             
                  assert_equal 8, type.fields.size
         | 
| 135 140 | 
             
                  assert_equal 9, type_2.fields.size
         | 
| 136 141 | 
             
                end
         |