diff --git a/lib/params/def.ex b/lib/params/def.ex index 230d238..fcb4ba7 100644 --- a/lib/params/def.ex +++ b/lib/params/def.ex @@ -126,6 +126,8 @@ defmodule Params.Def do defp field_call(meta) do cond do Keyword.get(meta, :field) -> :field + Keyword.get(meta, :embeds_one) -> :embeds_one + Keyword.get(meta, :embeds_many) -> :embeds_many Keyword.get(meta, :embeds) -> "embeds_#{Keyword.get(meta, :cardinality, :one)}" |> String.to_atom end @@ -137,11 +139,13 @@ defmodule Params.Def do cond do Keyword.get(meta, :field) -> Keyword.get(meta, :field) Keyword.get(meta, :embeds) -> module_concat(module, name) + Keyword.get(meta, :embeds_one) -> Keyword.get(meta, :embeds_one) + Keyword.get(meta, :embeds_many) -> Keyword.get(meta, :embeds_many) end end defp field_options(meta) do - Keyword.drop(meta, [:module, :name, :field, :embeds, :required, :cardinality]) + Keyword.drop(meta, [:module, :name, :field, :embeds, :embeds_one, :embeds_many, :required, :cardinality]) end def normalize_schema(dict, module) do @@ -156,6 +160,14 @@ defmodule Params.Def do normalize_field(v, [name: name, required: required, module: module]) end + defp normalize_field({:embeds_one, embed_module}, options) do + [embeds_one: embed_module] ++ options + end + + defp normalize_field({:embeds_many, embed_module}, options) do + [embeds_many: embed_module] ++ options + end + defp normalize_field(schema = %{}, options) do module = module_concat Keyword.get(options, :module), Keyword.get(options, :name) [embeds: normalize_schema(schema, module)] ++ options diff --git a/test/params_test.exs b/test/params_test.exs index 0a95f7d..5c22be0 100644 --- a/test/params_test.exs +++ b/test/params_test.exs @@ -136,6 +136,76 @@ defmodule ParamsTest do assert %Changeset{valid?: true} = kitten(params) end + defparams puppy %{ + breed!: :string, + age_min: :integer, + age_max: :integer, + near_location!: {:embeds_one, LocationParams} + } + + test "puppy module has list of required fields" do + assert [:near_location, :breed] = Params.required(Params.ParamsTest.Puppy) + end + + test "puppy module has list of optional fields" do + assert [:age_min, :age_max] = Params.optional(Params.ParamsTest.Puppy) + end + + test "puppy method returns changeset" do + assert %Changeset{} = puppy(%{}) + end + + test "puppy returns valid changeset when all data is ok" do + params = %{ + "breed" => "Russian Blue", + "age_min" => "0", + "age_max" => "4", + "near_location" => %{ + "latitude" => "87.5", + "longitude" => "-90.0" + } + } + assert %Changeset{valid?: true} = puppy(params) + end + + defparams dragon %{ + breed!: :string, + age_min: :integer, + age_max: :integer, + near_locations!: {:embeds_many, LocationParams} + } + + test "dragon module has list of required fields" do + assert [:near_locations, :breed] = Params.required(Params.ParamsTest.Dragon) + end + + test "dragon module has list of optional fields" do + assert [:age_min, :age_max] = Params.optional(Params.ParamsTest.Dragon) + end + + test "dragon method returns changeset" do + assert %Changeset{} = dragon(%{}) + end + + test "dragon returns valid changeset when all data is ok" do + params = %{ + "breed" => "Russian Blue", + "age_min" => "0", + "age_max" => "4", + "near_locations" => [ + %{ + "latitude" => "87.5", + "longitude" => "-90.0" + }, + %{ + "latitude" => "67.5", + "longitude" => "-60.0" + } + ] + } + assert %Changeset{valid?: true} = dragon(params) + end + defparams kid( %{ name: :string,