Skip to content

Commit

Permalink
Merge pull request #1009 from maartenvanvliet/issues/987
Browse files Browse the repository at this point in the history
Ensure interface nullable types can be implemented by non-nullable types
  • Loading branch information
benwilson512 committed Dec 25, 2020
2 parents 2678d02 + 670a05a commit eaedd98
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,15 @@ defmodule Absinthe.Phase.Schema.Validation.ObjectMustImplementInterfaces do
check_covariant(inner_type1, inner_type2, field_ident, types)
end

defp check_covariant(
itype,
%Absinthe.Blueprint.TypeReference.NonNull{of_type: inner_type},
field_ident,
types
) do
check_covariant(itype, inner_type, field_ident, types)
end

defp check_covariant(%{identifier: identifier}, %{identifier: identifier}, _field_ident, _types) do
:ok
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ defmodule Absinthe.Schema.Rule.ObjectMustImplementInterfacesTest do

object :user do
interface :named
interface :favorite_foods
field :name, :string
field :id, :id
field :parent, :named
field :another_parent, :user
field :color, non_null(list_of(non_null(:string)))
end
end

Expand All @@ -25,15 +27,40 @@ defmodule Absinthe.Schema.Rule.ObjectMustImplementInterfacesTest do
resolve_type fn
%{type: :dog}, _ -> :dog
%{type: :user}, _ -> :user
%{type: :cat}, _ -> :cat
_, _ -> nil
end
end

interface :favorite_foods do
field :color, list_of(:string)

resolve_type fn
%{type: :dog}, _ -> :dog
%{type: :user}, _ -> :user
%{type: :cat}, _ -> :cat
_, _ -> nil
end
end

object :dog do
field :name, :string
interface :named
interface :favorite_foods
field :parent, :named
field :another_parent, :user
field :color, list_of(non_null(:string))
end

# An object field type is a valid sub-type if it is a Non-Null variant of a
# valid sub-type of the interface field type.
object :cat do
interface :named
interface :favorite_foods
field :name, non_null(:string)
field :parent, :named
field :another_parent, :user
field :color, non_null(list_of(:string))
end

query do
Expand All @@ -53,21 +80,22 @@ defmodule Absinthe.Schema.Rule.ObjectMustImplementInterfacesTest do
end

test "interfaces are propogated across type imports" do
assert %{named: [:dog, :user]} == Schema.__absinthe_interface_implementors__()
assert %{named: [:cat, :dog, :user], favorite_foods: [:cat, :dog, :user]} ==
Schema.__absinthe_interface_implementors__()
end

test "is enforced" do
assert_schema_error("invalid_interface_types", [
%{
extra: %{
fields: [:name],
object: :user,
object: :foo,
interface: :named
},
locations: [
%{
file: "test/support/fixtures/dynamic/invalid_interface_types.exs",
line: 4
line: 13
}
],
phase: Absinthe.Phase.Schema.Validation.ObjectMustImplementInterfaces
Expand Down
2 changes: 1 addition & 1 deletion test/support/fixtures/dynamic/invalid_interface_types.exs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ defmodule Absinthe.Fixtures.InvalidInterfaceTypes do
end

interface :named do
field :name, :string
field :name, non_null(:string)
end

query do
Expand Down

0 comments on commit eaedd98

Please sign in to comment.