Skip to content

Commit def1794

Browse files
authored
Allow casting atoms as strings (open-api-spex#497)
1 parent 9e1d10a commit def1794

File tree

4 files changed

+34
-15
lines changed

4 files changed

+34
-15
lines changed

lib/open_api_spex/cast.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,14 @@ defmodule OpenApiSpex.Cast do
6565
iex> schema = %Schema{type: :string}
6666
iex> Cast.cast(schema, "a string")
6767
{:ok, "a string"}
68-
iex> Cast.cast(schema, :not_a_string)
68+
iex> Cast.cast(schema, 1..100)
6969
{
7070
:error,
7171
[
7272
%OpenApiSpex.Cast.Error{
7373
reason: :invalid_type,
7474
type: :string,
75-
value: :not_a_string
75+
value: 1..100
7676
}
7777
]
7878
}

lib/open_api_spex/cast/string.ex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ defmodule OpenApiSpex.Cast.String do
106106
{:ok, value}
107107
end
108108

109+
def cast(%{value: value} = ctx) when is_atom(value) and value not in [true, false, nil] do
110+
case cast(%{ctx | value: to_string(value)}) do
111+
{:ok, _value} -> {:ok, value}
112+
error -> error
113+
end
114+
end
115+
109116
def cast(%{value: value} = ctx) when is_binary(value) do
110117
apply_validation(ctx, @schema_fields)
111118
end

test/cast/string_test.exs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ defmodule OpenApiSpex.CastStringTest do
1515
assert error.value == %{}
1616
end
1717

18+
test "preserves atom values" do
19+
schema = %Schema{type: :string}
20+
21+
assert cast(value: :hello, schema: schema) == {:ok, :hello}
22+
end
23+
1824
test "string with pattern" do
1925
schema = %Schema{type: :string, pattern: ~r/\d-\d/}
2026
assert cast(value: "1-2", schema: schema) == {:ok, "1-2"}
@@ -80,6 +86,7 @@ defmodule OpenApiSpex.CastStringTest do
8086
# Note: we measure length of string after trimming leading and trailing whitespace
8187
test "minLength" do
8288
schema = %Schema{type: :string, minLength: 1}
89+
8390
assert {:ok, "a"} = cast(value: "a", schema: schema)
8491
assert {:error, [error]} = cast(value: "", schema: schema)
8592
assert %Error{} = error
@@ -89,27 +96,32 @@ defmodule OpenApiSpex.CastStringTest do
8996
# Note: we measure length of string after trimming leading and trailing whitespace
9097
test "maxLength" do
9198
schema = %Schema{type: :string, maxLength: 1}
99+
92100
assert {:ok, "a"} = cast(value: "a", schema: schema)
93-
assert {:error, [error]} = cast(value: "aa", schema: schema)
94-
assert %Error{} = error
95-
assert error.reason == :max_length
101+
assert {:error, [%Error{reason: :max_length}]} = cast(value: "aa", schema: schema)
102+
103+
assert {:ok, :a} = cast(value: :a, schema: schema)
104+
assert {:error, [%Error{reason: :max_length}]} = cast(value: :aa, schema: schema)
96105
end
97106

98107
test "maxLength and minLength" do
99108
schema = %Schema{type: :string, minLength: 1, maxLength: 2}
100-
assert {:error, [error]} = cast(value: "", schema: schema)
101-
assert %Error{} = error
102-
assert error.reason == :min_length
103-
assert {:error, [error]} = cast(value: "aaa", schema: schema)
104-
assert %Error{} = error
105-
assert error.reason == :max_length
109+
110+
assert {:error, [%Error{reason: :min_length}]} = cast(value: "", schema: schema)
111+
assert {:error, [%Error{reason: :max_length}]} = cast(value: "aaa", schema: schema)
112+
113+
assert {:error, [%Error{reason: :min_length}]} = cast(value: :"", schema: schema)
114+
assert {:error, [%Error{reason: :max_length}]} = cast(value: :aaa, schema: schema)
106115
end
107116

108117
test "minLength and pattern" do
109118
schema = %Schema{type: :string, minLength: 1, pattern: ~r/\d-\d/}
110-
assert {:error, errors} = cast(value: "", schema: schema)
111-
assert length(errors) == 2
112-
assert Enum.map(errors, & &1.reason) == [:invalid_format, :min_length]
119+
120+
assert {:error, [%Error{reason: :invalid_format}, %Error{reason: :min_length}]} =
121+
cast(value: "", schema: schema)
122+
123+
assert {:error, [%Error{reason: :invalid_format}, %Error{reason: :min_length}]} =
124+
cast(value: :"", schema: schema)
113125
end
114126
end
115127
end

test/test_assertions_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ defmodule OpenApiSpex.TestAssertionsTest do
1313

1414
test "failure" do
1515
schema = %Schema{type: :string}
16-
cast_context = %Cast{value: :nope, schema: schema}
16+
cast_context = %Cast{value: 1.100, schema: schema}
1717

1818
try do
1919
TestAssertions.assert_schema(cast_context)

0 commit comments

Comments
 (0)