Page MenuHomePhorge

No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/open_api_spex/cast_error.ex b/lib/open_api_spex/cast_error.ex
index 0b08c6a..0ff9f61 100644
--- a/lib/open_api_spex/cast_error.ex
+++ b/lib/open_api_spex/cast_error.ex
@@ -1,73 +1,73 @@
defmodule OpenApiSpex.CastError do
alias OpenApiSpex.TermType
defstruct reason: nil,
value: nil,
format: nil,
type: nil,
name: nil,
path: []
def new(ctx, {:invalid_type, type}) do
%__MODULE__{reason: :invalid_type, type: type}
|> add_context_fields(ctx)
end
def new(ctx, {:invalid_format, format}) do
%__MODULE__{reason: :invalid_format, format: format}
|> add_context_fields(ctx)
end
def new(ctx, {:unexpected_field, name}) do
%__MODULE__{reason: :unexpected_field, name: name}
|> add_context_fields(ctx)
end
def new(ctx, {:missing_field, name}) do
%__MODULE__{reason: :missing_field, name: name}
|> add_context_fields(ctx)
end
def message(%{reason: :invalid_type, type: type, value: value} = ctx) do
- prepend_path("Invalid #{type}: #{inspect(TermType.type(value))}", ctx)
+ prepend_path("Invalid #{type}. Got: #{TermType.type(value)}", ctx)
end
def message(%{reason: :polymorphic_failed, type: polymorphic_type} = ctx) do
prepend_path("Failed to cast to any schema in #{polymorphic_type}", ctx)
end
def message(%{reason: :unexpected_field, name: name} = ctx) do
prepend_path("Unexpected field: #{safe_string(name)}", ctx)
end
def message(%{reason: :no_value_required_for_discriminator, name: field} = ctx) do
prepend_path("No value for required disciminator property: #{field}", ctx)
end
def message(%{reason: :unknown_schema, name: name} = ctx) do
prepend_path("Unknown schema: #{name}", ctx)
end
def message(%{reason: :missing_field, name: name} = ctx) do
prepend_path("Missing field: #{name}", ctx)
end
defp add_context_fields(error, ctx) do
%{error | path: Enum.reverse(ctx.path), value: ctx.value}
end
defp prepend_path(message, ctx) do
path = "/" <> (ctx.path |> Enum.map(&to_string/1) |> Path.join())
"#" <> path <> ": " <> message
end
defp safe_string(string) do
to_string(string) |> String.slice(1..40)
end
end
defimpl String.Chars, for: OpenApiSpex.CastError do
def to_string(error) do
OpenApiSpex.CastError.message(error)
end
end
diff --git a/test/cast_test.exs b/test/cast_test.exs
index d7ba01a..2239da3 100644
--- a/test/cast_test.exs
+++ b/test/cast_test.exs
@@ -1,169 +1,171 @@
defmodule OpenApiSpec.CastTest do
use ExUnit.Case
alias OpenApiSpex.{Cast, CastContext, CastError, Reference, Schema}
def cast(ctx), do: Cast.cast(struct(CastContext, ctx))
describe "cast/3" do
# Note: full tests for primitives are covered in CastPrimitiveTest
test "primitives" do
tests = [
{:string, "1", :ok},
{:string, "", :ok},
{:string, true, :invalid},
{:string, nil, :invalid},
{:integer, 1, :ok},
{:integer, "1", :ok},
{:integer, %{}, :invalid},
- {:integer, nil, :invalid}
+ {:integer, nil, :invalid},
+ {:array, nil, :invalid},
+ {:object, nil, :invalid}
]
for {type, input, expected} <- tests do
case expected do
:ok -> assert {:ok, _} = cast(value: input, schema: %Schema{type: type})
:invalid -> assert {:error, _} = cast(value: input, schema: %Schema{type: type})
end
end
end
test "array" do
schema = %Schema{type: :array}
assert cast(value: [], schema: schema) == {:ok, []}
assert cast(value: [1, 2, 3], schema: schema) == {:ok, [1, 2, 3]}
assert cast(value: ["1", "2", "3"], schema: schema) == {:ok, ["1", "2", "3"]}
assert {:error, [error]} = cast(value: %{}, schema: schema)
assert %CastError{} = error
assert error.reason == :invalid_type
assert error.value == %{}
end
test "array with items schema" do
items_schema = %Schema{type: :integer}
schema = %Schema{type: :array, items: items_schema}
assert cast(value: [], schema: schema) == {:ok, []}
assert cast(value: [1, 2, 3], schema: schema) == {:ok, [1, 2, 3]}
assert cast(value: ["1", "2", "3"], schema: schema) == {:ok, [1, 2, 3]}
assert {:error, errors} = cast(value: [1, "two"], schema: schema)
assert [%CastError{} = error] = errors
assert error.reason == :invalid_type
assert error.value == "two"
assert error.path == [1]
end
# Additional object tests found in CastObjectTest
test "object with schema properties set, given known input property" do
schema = %Schema{
type: :object,
properties: %{age: nil}
}
assert cast(value: %{}, schema: schema) == {:ok, %{}}
assert cast(value: %{"age" => "hello"}, schema: schema) == {:ok, %{age: "hello"}}
end
test "reference" do
age_schema = %Schema{type: :integer}
assert cast(
value: "20",
schema: %Reference{"$ref": "#/components/schemas/Age"},
schemas: %{"Age" => age_schema}
) == {:ok, 20}
end
test "reference nested in object" do
age_schema = %Schema{type: :integer}
schema = %Schema{
type: :object,
properties: %{
age: %Reference{"$ref": "#/components/schemas/Age"}
}
}
assert cast(
value: %{"age" => "20"},
schema: schema,
schemas: %{"Age" => age_schema}
) == {:ok, %{age: 20}}
end
test "paths" do
schema = %Schema{
type: :object,
properties: %{
age: %Schema{type: :integer}
}
}
assert {:error, errors} = cast(value: %{"age" => "twenty"}, schema: schema)
assert [error] = errors
assert %CastError{} = error
assert error.path == [:age]
end
test "nested paths" do
schema = %Schema{
type: :object,
properties: %{
data: %Schema{
type: :object,
properties: %{
age: %Schema{type: :integer}
}
}
}
}
assert {:error, errors} = cast(value: %{"data" => %{"age" => "twenty"}}, schema: schema)
assert [error] = errors
assert %CastError{} = error
assert error.path == [:data, :age]
- assert to_string(error) == "#/data/age: Invalid integer: \"twenty\""
+ assert to_string(error) == "#/data/age: Invalid integer. Got: string"
end
test "paths involving arrays" do
schema = %Schema{
type: :object,
properties: %{
data: %Schema{
type: :array,
items: %Schema{
type: :object,
properties: %{
age: %Schema{type: :integer}
}
}
}
}
}
assert {:error, errors} =
cast(value: %{"data" => [%{"age" => "20"}, %{"age" => "twenty"}]}, schema: schema)
assert [error] = errors
assert %CastError{} = error
assert error.path == [:data, 1, :age]
- assert to_string(error) == "#/data/1/age: Invalid integer: \"twenty\""
+ assert to_string(error) == "#/data/1/age: Invalid integer. Got: string"
end
test "multiple errors" do
schema = %Schema{
type: :array,
items: %Schema{type: :integer}
}
value = [1, "two", 3, "four"]
assert {:error, errors} = cast(value: value, schema: schema)
assert [error, error2] = errors
assert %CastError{} = error
assert error.reason == :invalid_type
assert error.path == [1]
- assert to_string(error) == "#/1: Invalid integer: \"two\""
+ assert to_string(error) == "#/1: Invalid integer. Got: string"
- assert to_string(error2) == "#/3: Invalid integer: \"four\""
+ assert to_string(error2) == "#/3: Invalid integer. Got: string"
end
end
end

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 30, 5:58 PM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41517
Default Alt Text
(8 KB)

Event Timeline