module GraphQL::Compatibility::SchemaParserSpecification

This asserts that a given parse function turns a string into the proper tree of {{GraphQL::Language::Nodes}}.

Constants

SCHEMA_DEFINITION_STRING

Public Class Methods

build_suite(&block) click to toggle source

@yieldparam query_string [String] A query string to parse @yieldreturn [GraphQL::Language::Nodes::Document] @return [Class<Minitest::Test>] A test suite for this parse function

# File lib/graphql/compatibility/schema_parser_specification.rb, line 9
def self.build_suite(&block)
  Class.new(Minitest::Test) do
    @@parse_fn = block

    def parse(query_string)
      @@parse_fn.call(query_string)
    end

    def test_it_parses_object_types
      document = parse('
        # This is what
        # somebody said about something
        type Comment implements Node @deprecated(reason: "No longer supported") {
          id: ID!
        }
      ')

      type = document.definitions.first
      assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, type.class
      assert_equal 'Comment', type.name
      assert_equal "This is what\nsomebody said about something", type.description
      assert_equal ['Node'], type.interfaces.map(&:name)
      assert_equal ['id'], type.fields.map(&:name)
      assert_equal [], type.fields[0].arguments
      assert_equal 'ID', type.fields[0].type.of_type.name
      assert_equal 1, type.directives.length

      deprecated_directive = type.directives[0]
      assert_equal 'deprecated', deprecated_directive.name
      assert_equal 'reason', deprecated_directive.arguments[0].name
      assert_equal 'No longer supported', deprecated_directive.arguments[0].value
    end

    def test_it_parses_scalars
      document = parse('scalar DateTime')

      type = document.definitions.first
      assert_equal GraphQL::Language::Nodes::ScalarTypeDefinition, type.class
      assert_equal 'DateTime', type.name
    end

    def test_it_parses_enum_types
      document = parse('
        enum DogCommand {
          # Good dog
          SIT
          DOWN @deprecated(reason: "No longer supported")
          HEEL
        }
      ')

      type = document.definitions.first
      assert_equal GraphQL::Language::Nodes::EnumTypeDefinition, type.class
      assert_equal 'DogCommand', type.name
      assert_equal 3, type.values.length

      assert_equal 'SIT', type.values[0].name
      assert_equal [], type.values[0].directives
      assert_equal "Good dog", type.values[0].description

      assert_equal 'DOWN', type.values[1].name
      assert_equal 1, type.values[1].directives.length
      deprecated_directive = type.values[1].directives[0]
      assert_equal 'deprecated', deprecated_directive.name
      assert_equal 'reason', deprecated_directive.arguments[0].name
      assert_equal 'No longer supported', deprecated_directive.arguments[0].value

      assert_equal 'HEEL', type.values[2].name
      assert_equal [], type.values[2].directives
    end

    def test_it_parses_union_types
      document = parse(
        "union BagOfThings = \n"                "A |\n"                "B |\n"                "C"
      )

      union = document.definitions.first

      assert_equal GraphQL::Language::Nodes::UnionTypeDefinition, union.class
      assert_equal 'BagOfThings', union.name
      assert_equal 3, union.types.length
      assert_equal [1, 1], union.position

      assert_equal GraphQL::Language::Nodes::TypeName, union.types[0].class
      assert_equal 'A', union.types[0].name
      assert_equal [2, 1], union.types[0].position

      assert_equal GraphQL::Language::Nodes::TypeName, union.types[1].class
      assert_equal 'B', union.types[1].name
      assert_equal [3, 1], union.types[1].position

      assert_equal GraphQL::Language::Nodes::TypeName, union.types[2].class
      assert_equal 'C', union.types[2].name
      assert_equal [4, 1], union.types[2].position
    end

    def test_it_parses_input_types
      document = parse('
        input EmptyMutationInput {
          clientMutationId: String
        }
      ')

      type = document.definitions.first
      assert_equal GraphQL::Language::Nodes::InputObjectTypeDefinition, type.class
      assert_equal 'EmptyMutationInput', type.name
      assert_equal ['clientMutationId'], type.fields.map(&:name)
      assert_equal 'String', type.fields[0].type.name
      assert_equal nil, type.fields[0].default_value
    end

    def test_it_parses_directives
      document = parse('
        directive @include(if: Boolean!)
          on FIELD
          | FRAGMENT_SPREAD
          | INLINE_FRAGMENT
      ')

      type = document.definitions.first
      assert_equal GraphQL::Language::Nodes::DirectiveDefinition, type.class
      assert_equal 'include', type.name

      assert_equal 1, type.arguments.length
      assert_equal 'if', type.arguments[0].name
      assert_equal 'Boolean', type.arguments[0].type.of_type.name

      assert_equal 3, type.locations.length

      assert_instance_of GraphQL::Language::Nodes::DirectiveLocation, type.locations[0]
      assert_equal 'FIELD', type.locations[0].name
      assert_equal [3, 20], type.locations[0].position

      assert_instance_of GraphQL::Language::Nodes::DirectiveLocation, type.locations[1]
      assert_equal 'FRAGMENT_SPREAD', type.locations[1].name
      assert_equal [4, 19], type.locations[1].position

      assert_instance_of GraphQL::Language::Nodes::DirectiveLocation, type.locations[2]
      assert_equal 'INLINE_FRAGMENT', type.locations[2].name
      assert_equal [5, 19], type.locations[2].position
    end

    def test_it_parses_field_arguments
      document = parse('
        type Mutation {
          post(
            id: ID! @deprecated(reason: "Not used"),
            # This is what goes in the post
            data: String
          ): Post
        }
      ')

      field = document.definitions.first.fields.first
      assert_equal ['id', 'data'], field.arguments.map(&:name)
      id_arg = field.arguments[0]

      deprecated_directive = id_arg.directives[0]
      assert_equal 'deprecated', deprecated_directive.name
      assert_equal 'reason', deprecated_directive.arguments[0].name
      assert_equal 'Not used', deprecated_directive.arguments[0].value

      data_arg = field.arguments[1]
      assert_equal "data", data_arg.name
      assert_equal "This is what goes in the post", data_arg.description
    end

    def test_it_parses_schema_definition
      document = parse('
        schema {
          query: QueryRoot
          mutation: MutationRoot
          subscription: SubscriptionRoot
        }
      ')

      schema = document.definitions.first
      assert_equal 'QueryRoot', schema.query
      assert_equal 'MutationRoot', schema.mutation
      assert_equal 'SubscriptionRoot', schema.subscription
    end

    def test_it_parses_whole_definition_with_descriptions
      document = parse(SCHEMA_DEFINITION_STRING)

      assert_equal 6, document.definitions.size

      schema_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::SchemaDefinition, schema_definition.class

      directive_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::DirectiveDefinition, directive_definition.class
      assert_equal 'This is a directive', directive_definition.description

      enum_type_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::EnumTypeDefinition, enum_type_definition.class
      assert_equal "Multiline comment\n\nWith an enum", enum_type_definition.description

      assert_nil enum_type_definition.values[0].description
      assert_equal 'Not a creative color', enum_type_definition.values[1].description

      object_type_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, object_type_definition.class
      assert_equal 'Comment without preceding space', object_type_definition.description
      assert_equal 'And a field to boot', object_type_definition.fields[0].description

      input_object_type_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::InputObjectTypeDefinition, input_object_type_definition.class
      assert_equal 'Comment for input object types', input_object_type_definition.description
      assert_equal 'Color of the car', input_object_type_definition.fields[0].description

      interface_type_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::InterfaceTypeDefinition, interface_type_definition.class
      assert_equal 'Comment for interface definitions', interface_type_definition.description
      assert_equal 'Amount of wheels', interface_type_definition.fields[0].description

      brand_field = interface_type_definition.fields[1]
      assert_equal 1, brand_field.arguments.length
      assert_equal 'argument', brand_field.arguments[0].name
      assert_instance_of GraphQL::Language::Nodes::NullValue, brand_field.arguments[0].default_value
    end
  end
end

Public Instance Methods

parse(query_string) click to toggle source
# File lib/graphql/compatibility/schema_parser_specification.rb, line 13
def parse(query_string)
  @@parse_fn.call(query_string)
end
test_it_parses_directives() click to toggle source
# File lib/graphql/compatibility/schema_parser_specification.rb, line 123
def test_it_parses_directives
  document = parse('
    directive @include(if: Boolean!)
      on FIELD
      | FRAGMENT_SPREAD
      | INLINE_FRAGMENT
  ')

  type = document.definitions.first
  assert_equal GraphQL::Language::Nodes::DirectiveDefinition, type.class
  assert_equal 'include', type.name

  assert_equal 1, type.arguments.length
  assert_equal 'if', type.arguments[0].name
  assert_equal 'Boolean', type.arguments[0].type.of_type.name

  assert_equal 3, type.locations.length

  assert_instance_of GraphQL::Language::Nodes::DirectiveLocation, type.locations[0]
  assert_equal 'FIELD', type.locations[0].name
  assert_equal [3, 20], type.locations[0].position

  assert_instance_of GraphQL::Language::Nodes::DirectiveLocation, type.locations[1]
  assert_equal 'FRAGMENT_SPREAD', type.locations[1].name
  assert_equal [4, 19], type.locations[1].position

  assert_instance_of GraphQL::Language::Nodes::DirectiveLocation, type.locations[2]
  assert_equal 'INLINE_FRAGMENT', type.locations[2].name
  assert_equal [5, 19], type.locations[2].position
end
test_it_parses_enum_types() click to toggle source
# File lib/graphql/compatibility/schema_parser_specification.rb, line 50
def test_it_parses_enum_types
  document = parse('
    enum DogCommand {
      # Good dog
      SIT
      DOWN @deprecated(reason: "No longer supported")
      HEEL
    }
  ')

  type = document.definitions.first
  assert_equal GraphQL::Language::Nodes::EnumTypeDefinition, type.class
  assert_equal 'DogCommand', type.name
  assert_equal 3, type.values.length

  assert_equal 'SIT', type.values[0].name
  assert_equal [], type.values[0].directives
  assert_equal "Good dog", type.values[0].description

  assert_equal 'DOWN', type.values[1].name
  assert_equal 1, type.values[1].directives.length
  deprecated_directive = type.values[1].directives[0]
  assert_equal 'deprecated', deprecated_directive.name
  assert_equal 'reason', deprecated_directive.arguments[0].name
  assert_equal 'No longer supported', deprecated_directive.arguments[0].value

  assert_equal 'HEEL', type.values[2].name
  assert_equal [], type.values[2].directives
end
test_it_parses_field_arguments() click to toggle source
# File lib/graphql/compatibility/schema_parser_specification.rb, line 154
def test_it_parses_field_arguments
  document = parse('
    type Mutation {
      post(
        id: ID! @deprecated(reason: "Not used"),
        # This is what goes in the post
        data: String
      ): Post
    }
  ')

  field = document.definitions.first.fields.first
  assert_equal ['id', 'data'], field.arguments.map(&:name)
  id_arg = field.arguments[0]

  deprecated_directive = id_arg.directives[0]
  assert_equal 'deprecated', deprecated_directive.name
  assert_equal 'reason', deprecated_directive.arguments[0].name
  assert_equal 'Not used', deprecated_directive.arguments[0].value

  data_arg = field.arguments[1]
  assert_equal "data", data_arg.name
  assert_equal "This is what goes in the post", data_arg.description
end
test_it_parses_input_types() click to toggle source
# File lib/graphql/compatibility/schema_parser_specification.rb, line 108
def test_it_parses_input_types
  document = parse('
    input EmptyMutationInput {
      clientMutationId: String
    }
  ')

  type = document.definitions.first
  assert_equal GraphQL::Language::Nodes::InputObjectTypeDefinition, type.class
  assert_equal 'EmptyMutationInput', type.name
  assert_equal ['clientMutationId'], type.fields.map(&:name)
  assert_equal 'String', type.fields[0].type.name
  assert_equal nil, type.fields[0].default_value
end
test_it_parses_object_types() click to toggle source
# File lib/graphql/compatibility/schema_parser_specification.rb, line 17
def test_it_parses_object_types
  document = parse('
    # This is what
    # somebody said about something
    type Comment implements Node @deprecated(reason: "No longer supported") {
      id: ID!
    }
  ')

  type = document.definitions.first
  assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, type.class
  assert_equal 'Comment', type.name
  assert_equal "This is what\nsomebody said about something", type.description
  assert_equal ['Node'], type.interfaces.map(&:name)
  assert_equal ['id'], type.fields.map(&:name)
  assert_equal [], type.fields[0].arguments
  assert_equal 'ID', type.fields[0].type.of_type.name
  assert_equal 1, type.directives.length

  deprecated_directive = type.directives[0]
  assert_equal 'deprecated', deprecated_directive.name
  assert_equal 'reason', deprecated_directive.arguments[0].name
  assert_equal 'No longer supported', deprecated_directive.arguments[0].value
end
test_it_parses_scalars() click to toggle source
# File lib/graphql/compatibility/schema_parser_specification.rb, line 42
def test_it_parses_scalars
  document = parse('scalar DateTime')

  type = document.definitions.first
  assert_equal GraphQL::Language::Nodes::ScalarTypeDefinition, type.class
  assert_equal 'DateTime', type.name
end
test_it_parses_schema_definition() click to toggle source
# File lib/graphql/compatibility/schema_parser_specification.rb, line 179
def test_it_parses_schema_definition
  document = parse('
    schema {
      query: QueryRoot
      mutation: MutationRoot
      subscription: SubscriptionRoot
    }
  ')

  schema = document.definitions.first
  assert_equal 'QueryRoot', schema.query
  assert_equal 'MutationRoot', schema.mutation
  assert_equal 'SubscriptionRoot', schema.subscription
end
test_it_parses_union_types() click to toggle source
# File lib/graphql/compatibility/schema_parser_specification.rb, line 80
def test_it_parses_union_types
  document = parse(
    "union BagOfThings = \n"                "A |\n"                "B |\n"                "C"
  )

  union = document.definitions.first

  assert_equal GraphQL::Language::Nodes::UnionTypeDefinition, union.class
  assert_equal 'BagOfThings', union.name
  assert_equal 3, union.types.length
  assert_equal [1, 1], union.position

  assert_equal GraphQL::Language::Nodes::TypeName, union.types[0].class
  assert_equal 'A', union.types[0].name
  assert_equal [2, 1], union.types[0].position

  assert_equal GraphQL::Language::Nodes::TypeName, union.types[1].class
  assert_equal 'B', union.types[1].name
  assert_equal [3, 1], union.types[1].position

  assert_equal GraphQL::Language::Nodes::TypeName, union.types[2].class
  assert_equal 'C', union.types[2].name
  assert_equal [4, 1], union.types[2].position
end
test_it_parses_whole_definition_with_descriptions() click to toggle source
# File lib/graphql/compatibility/schema_parser_specification.rb, line 194
def test_it_parses_whole_definition_with_descriptions
  document = parse(SCHEMA_DEFINITION_STRING)

  assert_equal 6, document.definitions.size

  schema_definition = document.definitions.shift
  assert_equal GraphQL::Language::Nodes::SchemaDefinition, schema_definition.class

  directive_definition = document.definitions.shift
  assert_equal GraphQL::Language::Nodes::DirectiveDefinition, directive_definition.class
  assert_equal 'This is a directive', directive_definition.description

  enum_type_definition = document.definitions.shift
  assert_equal GraphQL::Language::Nodes::EnumTypeDefinition, enum_type_definition.class
  assert_equal "Multiline comment\n\nWith an enum", enum_type_definition.description

  assert_nil enum_type_definition.values[0].description
  assert_equal 'Not a creative color', enum_type_definition.values[1].description

  object_type_definition = document.definitions.shift
  assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, object_type_definition.class
  assert_equal 'Comment without preceding space', object_type_definition.description
  assert_equal 'And a field to boot', object_type_definition.fields[0].description

  input_object_type_definition = document.definitions.shift
  assert_equal GraphQL::Language::Nodes::InputObjectTypeDefinition, input_object_type_definition.class
  assert_equal 'Comment for input object types', input_object_type_definition.description
  assert_equal 'Color of the car', input_object_type_definition.fields[0].description

  interface_type_definition = document.definitions.shift
  assert_equal GraphQL::Language::Nodes::InterfaceTypeDefinition, interface_type_definition.class
  assert_equal 'Comment for interface definitions', interface_type_definition.description
  assert_equal 'Amount of wheels', interface_type_definition.fields[0].description

  brand_field = interface_type_definition.fields[1]
  assert_equal 1, brand_field.arguments.length
  assert_equal 'argument', brand_field.arguments[0].name
  assert_instance_of GraphQL::Language::Nodes::NullValue, brand_field.arguments[0].default_value
end