Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
solnic committed Oct 18, 2023
1 parent 85ff9cc commit 83a338a
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lib/drops/contract.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ defmodule Drops.Contract do
use Drops.Validator

alias Drops.Types
alias Drops.Contract.Messages

import Drops.Contract
import Drops.Contract.Runtime
Expand Down Expand Up @@ -103,6 +104,12 @@ defmodule Drops.Contract do
end
end

def errors({:error, errors}) do
Messages.errors(errors)
end

def errors({:ok, _}), do: []

def validate(data, keys) when is_list(keys) do
Enum.map(keys, &validate(data, &1)) |> List.flatten()
end
Expand Down
34 changes: 34 additions & 0 deletions lib/drops/contract/messages.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
defmodule Drops.Contract.Messages do
@moduledoc false

defmodule Error do
alias __MODULE__

defstruct [:path, :text, :opts]

defimpl String.Chars, for: Error do
def to_string(%Error{text: text}) do
text
end
end
end

def errors(results) do
Enum.map(results, &error/1)
end

defp error({:error, {path, predicate, [arg, value] = args}}) do
%Error{
path: path,
text: text(predicate, arg, value),
opts: %{
predicate: predicate,
args: args
}
}
end

defp text(:type?, :integer, _value) do
"must be an integer"
end
end
24 changes: 24 additions & 0 deletions test/contract/messages_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule Drops.Contract.MessagesTest do
use Drops.ContractCase

describe "errors/1" do
contract do
schema do
%{
required(:name) => string(),
required(:age) => integer()
}
end
end

test "returns a list with error structs", %{contract: contract} do
result = contract.conform(%{name: "Jane Doe", age: "twenty"})

assert [error = %{path: path, opts: opts}] = contract.errors(result)

assert path == [:age]
assert opts == %{predicate: :type?, args: [:integer, "twenty"]}
assert to_string(error) == "must be an integer"
end
end
end

0 comments on commit 83a338a

Please sign in to comment.