From dae35000b5b5cf5ecb7f680fc50c2dee64283ae3 Mon Sep 17 00:00:00 2001 From: Alex McLain Date: Tue, 20 Aug 2024 16:16:22 -0700 Subject: [PATCH] Fix issue with coercing a list of maps with a single attribute --- lib/mix/tasks/compiler.ex | 4 ++++ protocol/test/map_list_single.ex | 7 +++++++ test/speck_test.exs | 21 ++++++++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 protocol/test/map_list_single.ex diff --git a/lib/mix/tasks/compiler.ex b/lib/mix/tasks/compiler.ex index 483839e..e7310ac 100644 --- a/lib/mix/tasks/compiler.ex +++ b/lib/mix/tasks/compiler.ex @@ -152,6 +152,10 @@ defmodule Mix.Tasks.Compile.Speck do {name, [:map], [], Enum.map(attributes_ast, &build_attribute/1)} end + defp build_attribute({:attribute, _, [[name], [do: attributes_ast]]}) do + {name, [:map], [], [build_attribute(attributes_ast)]} + end + defp build_attribute({:attribute, _, [name, opts_ast, [do: {:__block__, _, attributes_ast}]]}) do {opts, _} = Code.eval_quoted(opts_ast) {name, :map, opts, Enum.map(attributes_ast, &build_attribute/1)} diff --git a/protocol/test/map_list_single.ex b/protocol/test/map_list_single.ex new file mode 100644 index 0000000..ad76965 --- /dev/null +++ b/protocol/test/map_list_single.ex @@ -0,0 +1,7 @@ +struct TestSchema.MapListSingleAttribute + +name "map_list_single_attribute" + +attribute [:devices] do + attribute :type, :string +end diff --git a/test/speck_test.exs b/test/speck_test.exs index fb71754..890738a 100644 --- a/test/speck_test.exs +++ b/test/speck_test.exs @@ -137,7 +137,26 @@ defmodule Speck.Test do }} end - test "can coerce a list of maps" do + test "can coerce a list of maps with a single attribute" do + params = %{ + "devices" => [ + %{"type" => "imx6"}, + %{"type" => "imx8"}, + %{"type" => "am62"}, + ] + } + + assert Speck.validate(TestSchema.MapListSingleAttribute, params) == + {:ok, %TestSchema.MapListSingleAttribute{ + devices: [ + %{type: "imx6"}, + %{type: "imx8"}, + %{type: "am62"}, + ] + }} + end + + test "can coerce a list of maps with multiple attributes" do params = %{ "devices" => [ %{"id" => 1, "type" => "valid"},