Skip to content

Commit

Permalink
Support custom regex for validation via config (#84)
Browse files Browse the repository at this point in the history
* Support custom regex for validation via config

* Add test cases

* Format
  • Loading branch information
lucca65 authored Mar 20, 2024
1 parent c1f0236 commit b43fbb8
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/goal.ex
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,9 @@ defmodule Goal do
{:format, %Regex{} = regex}, acc ->
validate_format(acc, field, regex)

{:format, key}, acc when is_atom(key) ->
validate_format(acc, field, Goal.Regex.custom(key))

{:less_than, integer}, acc ->
validate_number(acc, field, less_than: integer)

Expand Down
6 changes: 6 additions & 0 deletions lib/goal/regex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,10 @@ defmodule Goal.Regex do
~r/^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/
)
end

@doc false
@spec custom(atom()) :: Regex.t()
def custom(key) when is_atom(key) do
Application.get_env(:goal, String.to_atom("#{key}_regex"), nil)
end
end
11 changes: 11 additions & 0 deletions test/goal/regex_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,15 @@ defmodule Goal.RegexTest do
Application.delete_env(:goal, :url_regex)
end
end

describe "custom/1" do
test "with a custom regex" do
Application.put_env(:goal, :custom_regex, ~r/^[[:alpha:]]+$/)

assert String.match?("abc", Regex.custom(:custom)) == true
assert String.match?("123", Regex.custom(:custom)) == false

Application.delete_env(:goal, :custom_regex)
end
end
end
20 changes: 20 additions & 0 deletions test/goal_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ defmodule GoalTest do
optional(:type, :string, squish: true)
optional(:age, :integer, min: 0, max: 120)
optional(:gender, :enum, values: ["female", "male", "non-binary"])
optional(:hash, :string, format: :hash)

required :car, :map do
optional(:name, :string, min: 3, max: 20)
Expand Down Expand Up @@ -71,6 +72,7 @@ defmodule GoalTest do
type: [type: :string, squish: true],
age: [type: :integer, min: 0, max: 120],
gender: [type: :enum, values: ["female", "male", "non-binary"]],
hash: [type: :string, format: :hash],
car: [
type: :map,
required: true,
Expand Down Expand Up @@ -596,6 +598,24 @@ defmodule GoalTest do
assert errors_on(changeset_2) == %{id: ["has invalid format"]}
end

test "string, format: custom regex" do
Application.put_env(:goal, :custom_regex, ~r/^[a-fA-F0-9]{40}$/)

schema = %{hash: [type: :string, format: :custom]}

hash = :crypto.hash(:sha, "test") |> Base.encode16()
data_1 = %{"hash" => hash}
data_2 = %{"hash" => "notahash"}

changeset_1 = Goal.build_changeset(schema, data_1)
changeset_2 = Goal.build_changeset(schema, data_2)

assert changes_on(changeset_1) == %{hash: hash}
assert errors_on(changeset_2) == %{hash: ["has invalid format"]}

Application.delete_env(:goal, :custom_regex)
end

test "integer, is: 5" do
schema = %{age: [type: :integer, is: 5]}

Expand Down

0 comments on commit b43fbb8

Please sign in to comment.