Page MenuHomePhorge

No OneTemporary

Size
7 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/open_api_spex/cast_context.ex b/lib/open_api_spex/cast_context.ex
index 0c4a7d3..ec2d2d3 100644
--- a/lib/open_api_spex/cast_context.ex
+++ b/lib/open_api_spex/cast_context.ex
@@ -1,9 +1,23 @@
defmodule OpenApiSpex.CastContext do
+ alias OpenApiSpex.Error
+
defstruct value: nil,
schema: nil,
schemas: %{},
path: [],
key: nil,
index: 0,
errors: []
+
+ def error(ctx, {:invalid_type, type}) do
+ error = Error.new(:invalid_type, type, ctx.value)
+ error = %{error | path: Enum.reverse(ctx.path)}
+ {:error, [error | ctx.errors]}
+ end
+
+ def error(ctx, {:invalid_format, format}) do
+ error = Error.new(:invalid_format, format, ctx.value)
+ error = %{error | path: Enum.reverse(ctx.path)}
+ {:error, [error | ctx.errors]}
+ end
end
diff --git a/test/cast_primitive_test.exs b/test/cast_primitive_test.exs
index d9e6f11..66746ff 100644
--- a/test/cast_primitive_test.exs
+++ b/test/cast_primitive_test.exs
@@ -1,76 +1,76 @@
defmodule OpenApiSpex.CastPrimitiveTest do
use ExUnit.Case
alias OpenApiSpex.{CastContext, CastPrimitive, Error, Schema}
defp cast(ctx), do: CastPrimitive.cast(struct(CastContext, ctx))
describe "cast/3" do
@types [:boolean, :integer, :number, :string]
for type <- @types do
@type_value type
test "nil input for nullable:true, type:#{type}" do
schema = %Schema{type: @type_value, nullable: true}
assert cast(value: nil, schema: schema) == {:ok, nil}
end
test "nil input for nullable:false, type:#{type}" do
schema = %Schema{type: @type_value, nullable: false}
assert {:error, [error]} = cast(value: nil, schema: schema)
assert %Error{} = error
assert error.reason == :invalid_type
assert error.value == nil
end
end
test "boolean" do
schema = %Schema{type: :boolean}
assert cast(value: true, schema: schema) == {:ok, true}
assert cast(value: false, schema: schema) == {:ok, false}
assert cast(value: "true", schema: schema) == {:ok, true}
assert cast(value: "false", schema: schema) == {:ok, false}
assert {:error, [error]} = cast(value: "other", schema: schema)
assert %Error{reason: :invalid_type} = error
assert error.value == "other"
end
test "integer" do
schema = %Schema{type: :integer}
assert cast(value: 1, schema: schema) == {:ok, 1}
assert cast(value: 1.5, schema: schema) == {:ok, 2}
assert cast(value: "1", schema: schema) == {:ok, 1}
assert cast(value: "1.5", schema: schema) == {:ok, 2}
assert {:error, [error]} = cast(value: "other", schema: schema)
assert %Error{reason: :invalid_type} = error
assert error.value == "other"
end
test "number" do
schema = %Schema{type: :number}
assert cast(value: 1, schema: schema) == {:ok, 1.0}
assert cast(value: 1.5, schema: schema) == {:ok, 1.5}
assert cast(value: "1", schema: schema) == {:ok, 1.0}
assert cast(value: "1.5", schema: schema) == {:ok, 1.5}
assert {:error, [error]} = cast(value: "other", schema: schema)
assert %Error{reason: :invalid_type} = error
assert error.value == "other"
end
test "string" do
schema = %Schema{type: :string}
assert cast(value: "hello", schema: schema) == {:ok, "hello"}
assert cast(value: "", schema: schema) == {:ok, ""}
assert {:error, [error]} = cast(value: %{}, schema: schema)
assert %Error{reason: :invalid_type} = error
assert error.value == %{}
end
test "string with pattern" do
schema = %Schema{type: :string, pattern: ~r/\d-\d/}
assert cast(value: "1-2", schema: schema) == {:ok, "1-2"}
- assert {:error, error} = cast(value: "hello", schema: schema)
+ assert {:error, [error]} = cast(value: "hello", schema: schema)
assert error.reason == :invalid_format
assert error.value == "hello"
assert error.format == ~r/\d-\d/
end
end
end
diff --git a/test/support/cast_primitive.ex b/test/support/cast_primitive.ex
index 0ee9017..453edf7 100644
--- a/test/support/cast_primitive.ex
+++ b/test/support/cast_primitive.ex
@@ -1,93 +1,87 @@
defmodule OpenApiSpex.CastPrimitive do
@moduledoc false
- alias OpenApiSpex.Error
+ alias OpenApiSpex.CastContext
def cast(%{value: nil, schema: %{nullable: true}}),
do: {:ok, nil}
def cast(%{schema: %{type: :boolean}} = ctx),
do: cast_boolean(ctx)
def cast(%{schema: %{type: :integer}} = ctx),
do: cast_integer(ctx)
def cast(%{schema: %{type: :number}} = ctx),
do: cast_number(ctx)
def cast(%{schema: %{type: :string}} = ctx),
do: cast_string(ctx)
## Private functions
defp cast_boolean(%{value: value}) when is_boolean(value) do
{:ok, value}
end
defp cast_boolean(%{value: "true"}), do: {:ok, true}
defp cast_boolean(%{value: "false"}), do: {:ok, false}
defp cast_boolean(ctx) do
- error(:invalid_type, :boolean, ctx)
+ CastContext.error(ctx, {:invalid_type, :boolean})
end
defp cast_integer(%{value: value}) when is_integer(value) do
{:ok, value}
end
defp cast_integer(%{value: value}) when is_number(value) do
{:ok, round(value)}
end
defp cast_integer(%{value: value} = ctx) when is_binary(value) do
case Float.parse(value) do
{value, ""} -> cast_integer(%{ctx | value: value})
- _ -> error(:invalid_type, :integer, ctx)
+ _ -> CastContext.error(ctx, {:invalid_type, :integer})
end
end
defp cast_integer(ctx) do
- error(:invalid_type, :integer, ctx)
+ CastContext.error(ctx, {:invalid_type, :integer})
end
defp cast_number(%{value: value}) when is_number(value) do
{:ok, value}
end
defp cast_number(%{value: value}) when is_integer(value) do
{:ok, value / 1}
end
defp cast_number(%{value: value} = ctx) when is_binary(value) do
case Float.parse(value) do
{value, ""} -> {:ok, value}
- _ -> error(:invalid_type, :number, ctx)
+ _ -> CastContext.error(ctx, {:invalid_type, :number})
end
end
defp cast_number(ctx) do
- error(:invalid_type, :number, ctx)
+ CastContext.error(ctx, {:invalid_type, :number})
end
- defp cast_string(%{value: value, schema: %{pattern: pattern}})
+ defp cast_string(%{value: value, schema: %{pattern: pattern}} = ctx)
when not is_nil(pattern) and is_binary(value) do
if Regex.match?(pattern, value) do
{:ok, value}
else
- {:error, Error.new(:invalid_format, pattern, value)}
+ CastContext.error(ctx, {:invalid_format, pattern})
end
end
defp cast_string(%{value: value}) when is_binary(value) do
{:ok, value}
end
defp cast_string(ctx) do
- error(:invalid_type, :string, ctx)
- end
-
- defp error(:invalid_type, expected_type, ctx) do
- error = Error.new(:invalid_type, expected_type, ctx.value)
- error = %{error | path: Enum.reverse(ctx.path)}
- {:error, [error | ctx.errors]}
+ CastContext.error(ctx, {:invalid_type, :string})
end
end

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 30, 5:55 PM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41514
Default Alt Text
(7 KB)

Event Timeline