fix: handle builtin types in unions (#752)

This commit is contained in:
Robert Graff 2023-10-25 05:31:25 -07:00 committed by GitHub
parent d6c1445974
commit f03b6a4370
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 0 deletions

5
.gitpod.yml Normal file
View file

@ -0,0 +1,5 @@
image: elixir:latest
tasks:
- init: mix deps.get && mix compile
command: iex -S mix

View file

@ -521,6 +521,7 @@ defmodule Ash.Type.Union do
{:ok, type_config} <- Keyword.fetch(type_configs, type_name),
{:ok, type} <- Keyword.fetch(type_config, :type),
type_constraints <- Keyword.get(type_config, :constraints, []),
type <- Ash.Type.get_type(type),
{:ok, new_value} <- type.handle_change(nil, new_value, type_constraints) do
{:ok, %Ash.Union{type: type_name, value: new_value}}
end
@ -574,6 +575,7 @@ defmodule Ash.Type.Union do
{:ok, type_config} <- Keyword.fetch(type_configs, type_name),
{:ok, type} <- Keyword.fetch(type_config, :type),
type_constraints <- Keyword.get(type_config, :constraints, []),
type <- Ash.Type.get_type(type),
{:ok, value} <- type.prepare_change(old_value, new_value, type_constraints) do
{:ok, %Ash.Union{type: type_name, value: value}}
end

View file

@ -84,6 +84,62 @@ defmodule Ash.Test.Type.UnionTest do
assert {:error, _} = Ash.Type.cast_input(:union, 11, constraints)
end
test "it handles changes between native types" do
constraints = [
types: [
foo: [
type: :integer
],
bar: [
type: :string
]
]
]
assert {:ok, %Ash.Union{type: :bar, value: "bar"}} =
Ash.Type.Union.prepare_change(
%Ash.Union{type: :foo, value: 1},
"bar",
constraints
)
assert {:ok, %Ash.Union{type: :bar, value: "bar"}} =
Ash.Type.Union.handle_change(
%Ash.Union{type: :foo, value: 1},
%Ash.Union{type: :bar, value: "bar"},
constraints
)
end
test "it handles changes between native and tagged types" do
constraints = [
types: [
foo: [
type: Foo,
tag: :type,
tag_value: :foo
],
bar: [
type: :string
]
]
]
assert {:ok, %Ash.Union{type: :bar, value: "bar"}} =
Ash.Type.Union.prepare_change(
%Ash.Union{type: :foo, value: %Foo{}},
"bar",
constraints
)
assert {:ok, %Ash.Union{type: :bar, value: "bar"}} =
Ash.Type.Union.handle_change(
%Ash.Union{type: :foo, value: %{}},
%Ash.Union{type: :bar, value: "bar"},
constraints
)
end
test "it handles tagged types" do
constraints = [
types: [