Skip to content

Commit

Permalink
anyof and allof (#8)
Browse files Browse the repository at this point in the history
* More descriptive docs for path_or_nil and adding luacheck lints

* Have to run luarocks install separately for each package

* Adding more contributing docs

* Adding link to valid.lua

* Conistent function calling conventions in docs

* Adding allof and anyof validation functions
  • Loading branch information
benwilber authored May 19, 2024
1 parent 753e849 commit 260c995
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 0 deletions.
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ A library for Lua to validate various values and table structures.
- [`valid.arrayof`](#validarrayof)
- [`valid.map`](#validmap)
- [`valid.mapof`](#validmapof)
- [`valid.anyof`](#validanyof)
- [`valid.allof`](#validallof)
- [`valid.func`](#validfunc)
- [Error Handling and Invalid Propagation](#error-handling-and-invalid-propagation)
- [Contributing](#contributing)
Expand Down Expand Up @@ -385,6 +387,55 @@ assert(not is_valid) -- false, "name" is required for "bob"
* `empty`: Set to `true` to allow empty maps.
* `func`: A table containing two custom validation functions, one for the keys and one for the values.


### `valid.anyof`

Validates that a value satisfies at least one of the given validation functions.

#### Usage

```lua
local valid = require "valid"

local valid_string_or_number = valid.anyof {valid.string(), valid.number()}

local is_valid = valid_string_or_number "123"
assert(is_valid) -- true

local is_valid = valid_string_or_number {name = "joe"}
assert(not is_valid) -- false, not a string or number
```

#### Parameters

* `deffuncs` (required): An array table of one or more validation functions.


### `valid.allof`

Validates that a value satisfies all of the given validation functions.

#### Usage

```lua
local valid = require "valid"

local valid_word_and_number = valid.allof {
valid.string {pattern = "%w"},
valid.string {pattern = "^%d+$"}
}

local is_valid = valid_word_and_number("123")
assert(is_valid) -- true

local is_valid = valid_word_and_number {name = "joe"}
assert(not is_valid) -- false, not a string or number
```

#### Parameters

* `deffuncs` (required): An array table of one or more validation functions.

### `valid.func`

Validates that a value is a function.
Expand Down
53 changes: 53 additions & 0 deletions tests.lua
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,59 @@ describe("Validation Library Tests", function()
local simple_function = function() end

local tests = {
{
description = "Valid string or number",
definition = valid.anyof {valid.string(), valid.number()},
data = "this is a string",
expected = {
is_valid = true,
val_or_err = "this is a string",
badval_or_nil = nil,
path_or_nil = nil
}
},

{
description = "Invalid string or number",
definition = valid.anyof {valid.string(), valid.number()},
data = false,
expected = {
is_valid = false,
val_or_err = "any",
badval_or_nil = false,
path_or_nil = {
{"string", false},
{"number", false}
}
}
},

{
description = "Valid word and number patterns",
definition = valid.allof {valid.string {pattern = "%w"}, valid.string {pattern = "%d"}},
data = "123435",
expected = {
is_valid = true,
val_or_err = "123435",
badval_or_nil = nil,
path_or_nil = nil
}
},

{
description = "Invalid word and number patterns",
definition = valid.allof {valid.string {pattern = "%w"}, valid.string {pattern = "^%d$"}},
data = "123435 not a number",
expected = {
is_valid = false,
val_or_err = "all",
badval_or_nil = "123435 not a number",
path_or_nil = {
{"pattern", "123435 not a number"}
}
}
},

-- Valid simple function
{
description = "Valid simple function",
Expand Down
48 changes: 48 additions & 0 deletions valid.lua
Original file line number Diff line number Diff line change
Expand Up @@ -350,4 +350,52 @@ local function func()
end
_M.func = func

local function anyof(deffuncs)
return function(val)
local is_valid
local val_or_err
local badval_or_nil
local path_or_nil
local errtabs = {}

for _, deffunc in ipairs(deffuncs) do
is_valid, val_or_err, badval_or_nil, path_or_nil = deffunc(val)

if is_valid then
return true, val
else
errtabs[#errtabs + 1] = {val_or_err, badval_or_nil, path_or_nil}
end
end

return false, "any", val, errtabs
end
end
_M.anyof = anyof

local function allof(deffuncs)
return function(val)
local is_valid
local val_or_err
local badval_or_nil
local path_or_nil
local errtabs = {}

for _, deffunc in ipairs(deffuncs) do
is_valid, val_or_err, badval_or_nil, path_or_nil = deffunc(val)

if not is_valid then
errtabs[#errtabs + 1] = {val_or_err, badval_or_nil, path_or_nil}
end
end

if #errtabs == 0 then
return true, val
else
return false, "all", val, errtabs
end
end
end
_M.allof = allof

return _M

0 comments on commit 260c995

Please sign in to comment.