Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit 31a6911

Browse files
authored
Merge pull request #291 from coderplanets/editor-schema-validator
refactor(editor-validator): improve schema validator code
2 parents af6e913 + d3e255a commit 31a6911

File tree

5 files changed

+92
-22
lines changed

5 files changed

+92
-22
lines changed

lib/helper/utils.ex

+36
Original file line numberDiff line numberDiff line change
@@ -246,4 +246,40 @@ defmodule Helper.Utils do
246246
end
247247

248248
def str_occurence(_, _), do: "must be strings"
249+
250+
@spec large_than(String.t() | Integer.t(), Integer.t()) :: true | false
251+
def large_than(value, target) when is_binary(value) and is_integer(target) do
252+
String.length(value) >= target
253+
end
254+
255+
def large_than(value, target) when is_integer(value) and is_integer(target) do
256+
value >= target
257+
end
258+
259+
@spec large_than(String.t() | Integer.t(), Integer.t(), :no_equal) :: true | false
260+
def large_than(value, target, :no_equal) when is_binary(value) and is_integer(target) do
261+
String.length(value) > target
262+
end
263+
264+
def large_than(value, target, :no_equal) when is_integer(value) and is_integer(target) do
265+
value > target
266+
end
267+
268+
@spec less_than(String.t() | Integer.t(), Integer.t()) :: true | false
269+
def less_than(value, target) when is_binary(value) and is_integer(target) do
270+
String.length(value) <= target
271+
end
272+
273+
def less_than(value, target) when is_integer(value) and is_integer(target) do
274+
value <= target
275+
end
276+
277+
@spec less_than(String.t() | Integer.t(), Integer.t(), :no_equal) :: true | false
278+
def less_than(value, target, :no_equal) when is_binary(value) and is_integer(target) do
279+
String.length(value) < target
280+
end
281+
282+
def less_than(value, target, :no_equal) when is_integer(value) and is_integer(target) do
283+
value < target
284+
end
249285
end

lib/helper/validator/guards.ex

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
defmodule Helper.Validator.Guards do
2+
@moduledoc """
3+
general guards
4+
"""
5+
defguard g_pos_int(value) when is_integer(value) and value >= 0
6+
defguard g_not_nil(value) when not is_nil(value)
7+
end

lib/helper/validator/schema.ex

+15-21
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ defmodule Helper.Validator.Schema do
2323
data = %{checked: true, label: "done"}
2424
Schema.cast(schema, data)
2525
"""
26+
27+
alias Helper.Utils
28+
import Helper.Validator.Guards, only: [g_pos_int: 1, g_not_nil: 1]
29+
30+
@support_min [:string, :number]
31+
32+
@spec cast(map, map) :: {:ok, :pass} | {:error, map}
2633
def cast(schema, data) do
2734
errors_info = cast_errors(schema, data)
2835

@@ -62,11 +69,8 @@ defmodule Helper.Validator.Schema do
6269
{:ok, value}
6370

6471
false ->
65-
{:error,
66-
%{
67-
field: field,
68-
message: "should be: #{enum |> Enum.join(" | ")}"
69-
}}
72+
msg = %{field: field, message: "should be: #{enum |> Enum.join(" | ")}"}
73+
{:error, msg}
7074
end
7175
end
7276

@@ -78,22 +82,11 @@ defmodule Helper.Validator.Schema do
7882
end
7983

8084
# custom validate logic
81-
defp match(field, value, :string, [{:min, min} | options])
82-
when is_binary(value) and is_integer(min) do
83-
case String.length(value) >= min do
84-
true ->
85-
match(field, value, :string, options)
86-
87-
false ->
88-
error(field, value, :min, min)
89-
end
90-
end
91-
92-
defp match(field, value, :number, [{:min, min} | options])
93-
when is_integer(value) and is_integer(min) do
94-
case value >= min do
85+
defp match(field, value, type, [{:min, min} | options])
86+
when type in @support_min and g_not_nil(value) and g_pos_int(min) do
87+
case Utils.large_than(value, min) do
9588
true ->
96-
match(field, value, :number, options)
89+
match(field, value, type, options)
9790

9891
false ->
9992
error(field, value, :min, min)
@@ -109,13 +102,14 @@ defmodule Helper.Validator.Schema do
109102
defp match(field, value, :boolean, []) when is_boolean(value), do: done(field, value)
110103
# main type end
111104

112-
# judge option
105+
# error for option
113106
defp match(field, value, type, [option]) when is_tuple(option) do
114107
# 如果这里不判断的话会和下面的 match 冲突,是否有更好的写法?
115108
case option_valid?(option) do
116109
true ->
117110
error(field, value, type)
118111

112+
# unknow option or option not valid
119113
false ->
120114
{k, v} = option
121115
error(field, value, option: "#{to_string(k)}: #{to_string(v)}")

test/helper/utils_test.exs

+34
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,38 @@ defmodule GroupherServer.Test.Helper.UtilsTest do
128128
assert 0 == Utils.str_occurence("hello world", "foo")
129129
end
130130
end
131+
132+
describe "[basic compare]" do
133+
test "large_than work for both number and string" do
134+
assert true == Utils.large_than(10, 9)
135+
assert false == Utils.large_than(8, 9)
136+
137+
assert true == Utils.large_than("lang", 3)
138+
assert false == Utils.large_than("ok", 3)
139+
end
140+
141+
test "large_than equal case" do
142+
assert true == Utils.large_than(9, 9)
143+
assert false == Utils.large_than(9, 9, :no_equal)
144+
145+
assert true == Utils.large_than("lang", 4)
146+
assert false == Utils.large_than("lang", 4, :no_equal)
147+
end
148+
149+
test "less_than work for both number and string" do
150+
assert false == Utils.less_than(10, 9)
151+
assert true == Utils.less_than(8, 9)
152+
153+
assert false == Utils.less_than("lang", 3)
154+
assert true == Utils.less_than("ok", 3)
155+
end
156+
157+
test "less_than equal case" do
158+
assert true == Utils.less_than(9, 9)
159+
assert false == Utils.less_than(9, 9, :no_equal)
160+
161+
assert true == Utils.less_than("lang", 4)
162+
assert false == Utils.less_than("lang", 4, :no_equal)
163+
end
164+
end
131165
end

test/helper/validator/schema_test.exs

-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ defmodule GroupherServer.Test.Helper.Validator.Schema do
8585
# hello world
8686
end
8787

88-
@tag :wip2
8988
test "number with wrong option" do
9089
schema = %{"text" => [:number, required: true, min: "5"]}
9190
data = %{"text" => 1}

0 commit comments

Comments
 (0)