graphql-client/test/test_schema.rb

435 строки
13 KiB
Ruby

# frozen_string_literal: true
require "graphql"
require "graphql/client/schema"
require "minitest/autorun"
require "time"
class TestSchemaType < MiniTest::Test
GraphQL::DeprecatedDSL.activate if GraphQL::VERSION > "1.8"
DateTime = GraphQL::ScalarType.define do
name "DateTime"
coerce_input ->(value, ctx) do
Time.iso8601(value)
end
coerce_result ->(value, ctx) do
value.utc.iso8601
end
end
NodeArgInput = GraphQL::InputObjectType.define do
name "NodeInput"
argument :id, !types.String
end
NodeType = GraphQL::InterfaceType.define do
name "Node"
field :id, !types.ID do
argument :input, NodeArgInput
end
end
PlanEnum = GraphQL::EnumType.define do
name "Plan"
value "FREE"
value "SMALL"
value "LARGE"
value "other"
end
PersonType = GraphQL::ObjectType.define do
name "Person"
interfaces [NodeType]
field :name, !types.String
field :firstName, !types.String
field :lastName, !types.String
field :age, !types.Int
field :birthday, !DateTime
field :friends, !types[!PersonType]
field :plan, !PlanEnum
end
PhotoType = GraphQL::ObjectType.define do
name "Photo"
field :height, !types.Int
field :width, !types.Int
end
SearchResultUnion = GraphQL::UnionType.define do
name "SearchResult"
possible_types [PersonType, PhotoType]
end
QueryType = GraphQL::ObjectType.define do
name "Query"
field :me, !PersonType
field :node, NodeType
field :firstSearchResult, !SearchResultUnion
end
Schema = GraphQL::Schema.define(query: QueryType) do
resolve_type ->(_type, _obj, _ctx) { raise NotImplementedError }
end
Types = GraphQL::Client::Schema.generate(Schema)
def test_query_object_class
assert_equal QueryType, Types::Query.type
assert_equal "TestSchemaType::Types::Query", Types::Query.inspect
end
def test_person_object_class
assert Types::Person < Types::Node
assert Types::Person < Types::SearchResult
assert_equal PersonType, Types::Person.type
assert_equal "TestSchemaType::Types::Person", Types::Person.inspect
end
def test_photo_object_class
refute Types::Photo < Types::Node
assert Types::Photo < Types::SearchResult
assert_equal PhotoType, Types::Photo.type
assert_equal "TestSchemaType::Types::Photo", Types::Photo.inspect
end
def test_id_scalar_object
assert_equal GraphQL::ID_TYPE, Types::ID.type
assert_kind_of GraphQL::Client::Schema::ScalarType, Types::ID
end
def test_string_scalar_object
assert_equal GraphQL::STRING_TYPE, Types::String.type
end
def test_int_scalar_object
assert_equal GraphQL::INT_TYPE, Types::Int.type
end
def test_datetime_scalar_object
assert_equal DateTime, Types::DateTime.type
assert_equal Time.at(0), Types::DateTime.cast(Time.at(0).iso8601)
end
def test_boolean_scalar_object
assert_equal GraphQL::BOOLEAN_TYPE, Types::Boolean.type
end
def test_node_interface_module
assert_kind_of GraphQL::Client::Schema::InterfaceType, Types::Node
assert_equal NodeType, Types::Node.type
assert_equal "TestSchemaType::Types::Node", Types::Node.inspect
end
def test_search_result_union
assert_kind_of GraphQL::Client::Schema::UnionType, Types::SearchResult
assert_equal SearchResultUnion, Types::SearchResult.type
assert_equal "TestSchemaType::Types::SearchResult", Types::SearchResult.inspect
end
def test_plan_enum_constants
assert_kind_of GraphQL::Client::Schema::EnumType, Types::Plan
assert_equal PlanEnum, Types::Plan.type
assert_equal "TestSchemaType::Types::Plan", Types::Plan.inspect
assert_equal "FREE", Types::Plan.cast("FREE")
assert_equal "FREE", Types::Plan::FREE
assert_equal "SMALL", Types::Plan::SMALL
assert_equal "LARGE", Types::Plan::LARGE
assert_equal "FREE", Types::Plan["FREE"]
assert_equal "SMALL", Types::Plan["SMALL"]
assert_equal "LARGE", Types::Plan["LARGE"]
assert Types::Plan::FREE.free?
refute Types::Plan::FREE.small?
refute Types::Plan::FREE.large?
refute Types::Plan::SMALL.free?
assert Types::Plan::SMALL.small?
refute Types::Plan::SMALL.large?
end
def test_to_non_null_type
assert non_null_person = Types::Person.to_non_null_type
assert_kind_of GraphQL::Client::Schema::NonNullType, non_null_person
assert non_null_person.equal?(Types::Person.to_non_null_type)
assert non_null_person.to_non_null_type.equal?(Types::Person.to_non_null_type)
assert non_null_photo = Types::Photo.to_non_null_type
assert_kind_of GraphQL::Client::Schema::NonNullType, non_null_photo
assert non_null_photo.equal?(Types::Photo.to_non_null_type)
refute non_null_photo.equal?(non_null_person)
end
def test_to_list_type
assert person_list = Types::Person.to_list_type
assert_kind_of GraphQL::Client::Schema::ListType, person_list
assert person_list.equal?(Types::Person.to_list_type)
assert person_list.to_list_type.equal?(Types::Person.to_list_type)
assert photo_list = Types::Photo.to_list_type
assert_kind_of GraphQL::Client::Schema::ListType, photo_list
assert photo_list.equal?(Types::Photo.to_list_type)
refute photo_list.equal?(person_list)
end
def test_person_fields
assert_kind_of GraphQL::Client::Schema::NonNullType, Types::Person.fields[:name]
assert_equal Types::String, Types::Person.fields[:name].of_klass
assert_kind_of GraphQL::Client::Schema::NonNullType, Types::Person.fields[:friends]
assert_kind_of GraphQL::Client::Schema::ListType, Types::Person.fields[:friends].of_klass
assert_kind_of GraphQL::Client::Schema::NonNullType, Types::Person.fields[:friends].of_klass.of_klass
assert_kind_of GraphQL::Client::Schema::ObjectType, Types::Person.fields[:friends].of_klass.of_klass.of_klass
assert_equal Types::Person, Types::Person.fields[:friends].of_klass.of_klass.of_klass
assert_kind_of GraphQL::Client::Schema::NonNullType, Types::Person.fields[:id]
assert_equal Types::ID, Types::Person.fields[:id].of_klass
end
def test_query_object_subclass
query_klass = Class.new(Types::Query)
person_klass = Class.new(Types::Person)
assert_equal QueryType, query_klass.type
assert_equal PersonType, person_klass.type
query_klass.define_field :me, person_klass
assert_includes query_klass.instance_methods, :me
person_klass.define_field :id, Types::Person.fields[:id]
assert_includes person_klass.instance_methods, :id
assert query = query_klass.new({
"me" => {
"id" => "1"
}
})
assert_kind_of Types::Person, query.me
assert_kind_of person_klass, query.me
assert_equal "1", query.me.id
assert_match "#<TestSchemaType::Types::Query", query.inspect
assert_raises NoMethodError do
query.todo
end
end
def test_person_object_subclass
friend_klass = Class.new(Types::Person)
friend_klass.define_field :id, Types::Person.fields[:id]
friend_klass.define_field :name, Types::Person.fields[:name]
person_klass = Class.new(Types::Person)
person_klass.define_field :id, Types::Person.fields[:id]
person_klass.define_field :name, Types::Person.fields[:name]
person_klass.define_field :firstName, Types::Person.fields[:firstName]
person_klass.define_field :lastName, Types::Person.fields[:lastName]
person_klass.define_field :birthday, Types::Person.fields[:birthday]
person_klass.define_field :plan, Types::Person.fields[:plan]
person_klass.define_field :friends, GraphQL::Client::Schema::NonNullType.new(
GraphQL::Client::Schema::ListType.new(
GraphQL::Client::Schema::NonNullType.new(
friend_klass)))
assert_includes person_klass.instance_methods, :id
assert_includes person_klass.instance_methods, :name
assert_includes person_klass.instance_methods, :first_name
assert_includes person_klass.instance_methods, :last_name
assert_includes person_klass.instance_methods, :plan
assert person = person_klass.new({
"id" => "1",
"name" => "Josh",
"firstName" => "Joshua",
"lastName" => "Peek",
"birthday" => Time.at(0).iso8601,
"plan" => "FREE",
"friends" => [{
"id" => "2",
"name" => "David"
}]
})
assert_kind_of person_klass, person
assert_kind_of Types::Person, person
assert_kind_of Types::Node, person
refute person.errors.any?
assert_equal "1", person.id
assert_equal "Josh", person.name
assert_equal true, person.name?
assert_equal "Joshua", person.first_name
assert_equal "Peek", person.last_name
assert_equal Time.at(0), person.birthday
assert_equal true, person.plan.free?
assert_equal 1, person.friends.length
assert_equal "2", person.friends[0].id
assert_equal "David", person.friends[0].name
assert_same Types::Plan::FREE, person.plan
assert_equal({
"id" => "1",
"name" => "Josh",
"firstName" => "Joshua",
"lastName" => "Peek",
"birthday" => Time.at(0).iso8601,
"plan" => "FREE",
"friends" => [{
"id" => "2",
"name" => "David"
}]
}, person.to_h)
assert_match "#<TestSchemaType::Types::Person", person.inspect
assert_raises NoMethodError do
person.age
end
refute person.respond_to?(:missing)
assert_equal "Person", person.class.type.name
assert person.is_a?(Types::Person)
assert person.is_a?(Types::Node)
refute person.is_a?(Types::Photo)
assert_equal "Joshua", person.first_name
end
def test_transform_lowercase_type_name
person_type = GraphQL::ObjectType.define do
name "person"
field :name, !types.String
end
photo_type = GraphQL::ObjectType.define do
name "photo"
field :height, !types.Int
field :width, !types.Int
end
search_result_union = GraphQL::UnionType.define do
name "search_result"
possible_types [person_type, photo_type]
end
query_type = GraphQL::ObjectType.define do
name "query"
field :me, !person_type
field :first_search_result, !search_result_union
end
schema = GraphQL::Schema.define(query: query_type) do
resolve_type ->(_type, _obj, _ctx) { raise NotImplementedError }
end
types = GraphQL::Client::Schema.generate(schema)
assert_equal person_type, types::Person.type
assert_equal photo_type, types::Photo.type
assert_equal search_result_union, types::SearchResult.type
end
def test_reject_colliding_type_names
underscored_type = GraphQL::ObjectType.define do
name "search_result"
field :title, !types.String
end
camelcase_type = GraphQL::ObjectType.define do
name "SearchResult"
field :title, !types.String
end
query_type = GraphQL::ObjectType.define do
name "query"
field :result, !underscored_type
field :other_result, !camelcase_type
end
schema = GraphQL::Schema.define(query: query_type) do
resolve_type ->(_type, _obj, _ctx) { raise NotImplementedError }
end
assert_raises ArgumentError do
GraphQL::Client::Schema.generate(schema)
end
end
def test_interface_cast
query_klass = Class.new(Types::Query)
person_klass = Class.new(Types::Person)
node_klass = Types::Node.new([person_klass])
assert_equal NodeType, node_klass.type
query_klass.define_field :node, node_klass
assert_includes query_klass.instance_methods, :node
person_klass.define_field :id, Types::Person.fields[:id]
assert_includes person_klass.instance_methods, :id
assert query = query_klass.new({
"node" => {
"__typename" => "Person",
"id" => "1"
}
})
assert_kind_of Types::Node, query.node
assert_kind_of Types::Person, query.node
assert_kind_of person_klass, query.node
assert_equal "1", query.node.id
end
def test_union_cast
query_klass = Class.new(Types::Query)
person_klass = Class.new(Types::Person)
search_result_klass = Types::SearchResult.new([person_klass])
assert_equal SearchResultUnion, search_result_klass.type
query_klass.define_field :firstSearchResult, search_result_klass
assert_includes query_klass.instance_methods, :first_search_result
person_klass.define_field :id, Types::Person.fields[:id]
assert_includes person_klass.instance_methods, :id
assert query = query_klass.new({
"firstSearchResult" => {
"__typename" => "Person",
"id" => "1"
}
})
assert_kind_of Types::Person, query.first_search_result
assert_kind_of person_klass, query.first_search_result
assert_equal "1", query.first_search_result.id
end
def test_skip_directive
assert klass = Types.directives[:skip]
assert maybe_plan = klass.new(Types::Plan)
assert_nil maybe_plan.cast(nil, nil)
assert_equal Types::Plan::FREE, maybe_plan.cast("FREE", nil)
end
def test_include_directive
assert klass = Types.directives[:include]
assert maybe_plan = klass.new(Types::Plan)
assert_nil maybe_plan.cast(nil, nil)
assert_equal Types::Plan::FREE, maybe_plan.cast("FREE", nil)
end
end