Skip to content

Commit

Permalink
Hack - attempt at support for dynamic Enum values
Browse files Browse the repository at this point in the history
  • Loading branch information
binaryseed committed Jan 3, 2021
1 parent e64229a commit 80f2660
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 17 deletions.
3 changes: 2 additions & 1 deletion .formatter.exs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ locals_without_parens = [
types: 1,
union: 3,
value: 1,
value: 2
value: 2,
values: 1
]

[
Expand Down
2 changes: 1 addition & 1 deletion lib/absinthe/blueprint/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ defmodule Absinthe.Blueprint.Schema do
end

defp build_types([{:values, values} | rest], [enum | stack], buff) do
enum = Map.update!(enum, :values, &(values ++ &1))
enum = Map.update!(enum, :values, &(List.wrap(values) ++ &1))
build_types(rest, [enum | stack], buff)
end

Expand Down
42 changes: 31 additions & 11 deletions lib/absinthe/blueprint/schema/enum_type_definition.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,37 @@ defmodule Absinthe.Blueprint.Schema.EnumTypeDefinition do
end

def values_by(type_def, key) do
for value_def <- type_def.values, into: %{} do
value = %Absinthe.Type.Enum.Value{
name: value_def.name,
value: value_def.value,
enum_identifier: type_def.identifier,
__reference__: value_def.__reference__,
description: value_def.description,
deprecation: value_def.deprecation
}

{Map.fetch!(value_def, key), value}
for value_def <- List.flatten(type_def.values), into: %{} do
case value_def do
%Blueprint.Schema.EnumValueDefinition{} ->
value = %Absinthe.Type.Enum.Value{
name: value_def.name,
value: value_def.value,
enum_identifier: type_def.identifier,
__reference__: value_def.__reference__,
description: value_def.description,
deprecation: value_def.deprecation
}

{Map.fetch!(value_def, key), value}

raw_value ->
name = raw_value |> to_string() |> String.upcase()

value_def = %{
name: name,
value: raw_value,
identifier: raw_value
}

value = %Absinthe.Type.Enum.Value{
name: name,
value: raw_value,
enum_identifier: type_def.identifier
}

{Map.fetch!(value_def, key), value}
end
end
end

Expand Down
5 changes: 1 addition & 4 deletions lib/absinthe/schema/notation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1494,10 +1494,7 @@ defmodule Absinthe.Schema.Notation do
values =
values
|> expand_ast(env)
|> Enum.map(fn ident ->
value_attrs = handle_enum_value_attrs(ident, [], env)
struct!(Schema.EnumValueDefinition, value_attrs)
end)
|> wrap_in_unquote

put_attr(env.module, {:values, values})
end
Expand Down
14 changes: 14 additions & 0 deletions test/absinthe/type/enum_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ defmodule Absinthe.Type.EnumTest do
value :blue, as: color(:blue)
end

enum :dynamic_color_list do
values color_list()
end

def color_list, do: [:purple, :orange, :yellow]

def color(:red), do: {255, 0, 0}
def color(:green), do: {0, 255, 0}
def color(:blue), do: {0, 0, 255}
Expand Down Expand Up @@ -89,6 +95,14 @@ defmodule Absinthe.Type.EnumTest do
assert %Type.Enum.Value{name: "GREEN", value: {0, 255, 0}} = type.values[:green]
assert %Type.Enum.Value{name: "BLUE", value: {0, 0, 255}} = type.values[:blue]
end

test "values can be defined dynamically too" do
type = TestSchema.__absinthe_type__(:dynamic_color_list)

assert %Type.Enum.Value{name: "YELLOW"} = type.values[:yellow]
assert %Type.Enum.Value{name: "PURPLE"} = type.values[:purple]
assert %Type.Enum.Value{name: "ORANGE"} = type.values[:orange]
end
end

describe "enum value description evaluation" do
Expand Down

0 comments on commit 80f2660

Please sign in to comment.