diff --git a/src/bag.nim b/src/bag.nim old mode 100644 new mode 100755 index 3acc77d..130d293 --- a/src/bag.nim +++ b/src/bag.nim @@ -9,7 +9,7 @@ import std/[macros, tables, times, strutils] type TField* = enum - tNone # used to ignore buttons or submit/reset inputs + tNone # used to ignore `button`, `submit`, `reset` elements tCheckbox tColor tDate @@ -299,7 +299,7 @@ proc parseRule(rule: NimNode, isRequired = true): NimNode {.compileTime.} = handleFilters(r[1]) result = newRule -macro newBag*(data, rules) = +macro bag*(data: typed, rules: untyped, bodyFail: untyped = nil) = ## Create a new input bag validation at compile time. ## ## `data` expects a `seq[tuple[k, v: string]]` @@ -312,15 +312,21 @@ macro newBag*(data, rules) = ("password", "123admin"), ("remember", "on") ] - newBag data: + bag data: email: tEmail or "Invalid email address" password: tPassword or "Invalid password" *remember: tCheckbox # optional field, default: off/false + do: + # a runnable block of code in case validation fails + # `return` may be required to block code execution + echo "oups!" + return + echo "ok" expectKind rules, nnkStmtList result = newStmtList() let varBagInstance = newVarStmt( - ident "Bag", + ident "inputBag", newCall(ident "InputBag") ) var rulesList = newStmtList() @@ -331,7 +337,7 @@ macro newBag*(data, rules) = rulesList.add( newCall( ident "addRule", - ident "Bag", + ident "inputBag", node ) ) @@ -342,4 +348,8 @@ macro newBag*(data, rules) = result.add varBagInstance result.add rulesList result.add quote do: - Bag.validate(`data`) \ No newline at end of file + inputBag.validate(`data`) + if bodyFail != nil: + result.add quote do: + if inputBag.isInvalid: + `bodyFail` \ No newline at end of file diff --git a/tests/test1.nim b/tests/test1.nim old mode 100644 new mode 100755 index 7bdaa78..91d172a --- a/tests/test1.nim +++ b/tests/test1.nim @@ -8,7 +8,7 @@ test "can find errors": ("message", "Lorem ipsum something better than that") ] - newBag fields: + bag fields: text: tText or "auth.error.name" email: tEmail or "auth.error.email" password: tPassword or "auth.error.password" @@ -16,75 +16,75 @@ test "can find errors": min: 10 or "comment.message.min" max: 20 or "comment.message.max" *remember: tCheckbox - - check Bag.isValid == false - check Bag.getErrors[0][1] == "auth.error.email" - check Bag.getErrors[1][1] == "auth.error.password" - check Bag.getErrors[2][1] == "comment.message.max" + # do: + # check inputBag.isValid == false + # check inputBag.getErrors[0][1] == "auth.error.email" + # check inputBag.getErrors[1][1] == "auth.error.password" + # check inputBag.getErrors[2][1] == "comment.message.max" test "check tDate": let invalid = [("birthday", "1999-05-05")] let valid = [("birthday", "2001-05-05")] for data in [invalid, valid]: - newBag data: + bag data: birthday: tDate("yyyy-MM-dd") or "invalid.date": min: "2000-12-01" or "invalid.date.min" max: "2010-05-06" or "invalid.date.min" - if not Bag.isValid: - check(Bag.getErrors[0][1] == "invalid.date.min") + # do: + # check(inputBag.getErrors[0][1] == "invalid.date.min") test "check tPassword": for data in [[("mypassword", "1234")], [("mypassword", "/iwJN_zCO#@k")]]: - newBag data: + bag data: mypassword: tPassword or "requires.password": min: 10 or "invalid.password.min" max: 13 or "invalid.password.max" - if not Bag.isValid: - check Bag.getErrors[0][1] == "invalid.password.min" + do: + check inputBag.getErrors[0][1] == "invalid.password.min" test "check TCheckbox": let invalid = [("mycheckbox", "yes")] let valid = [("mycheckbox", "true")] proc checkValid() = - newBag valid: + bag valid: mycheckbox: tCheckbox or "invalid.checkbox" - check Bag.isValid == true - check(Bag.getErrors.len == 0) + # check Bag.isValid == true + # check(Bag.getErrors.len == 0) proc checkInvalid() = - newBag invalid: + bag invalid: mycheckbox: tCheckbox or "invalid.checkbox" - check Bag.isValid == false - check(Bag.getErrors.len == 1) - check(Bag.getErrors[0][1] == "invalid.checkbox") + # check Bag.isValid == false + # check(Bag.getErrors.len == 1) + # check(Bag.getErrors[0][1] == "invalid.checkbox") checkValid() checkInvalid() test "check tSelect": for data in [[("region", "ibiza")], [("region", "kefalonia")]]: - newBag data: + bag data: region: tSelect: options: ["kefalonia", "paros"] or "unknown.region" - if not Bag.isValid: - check Bag.getErrors[0][1] == "unknown.region" + # if not Bag.isValid: + # check Bag.getErrors[0][1] == "unknown.region" test "check tPasswordStrength": let invalid = [("mypass", "sunandmoon12")] let valid = [("mypass", "x6y2C8Dt5Lgg")] proc checkValid() = - newBag valid: + bag valid: mypass: tPasswordStrength or "invalid.pass" - check Bag.isValid == true - check(Bag.getErrors.len == 0) + # check Bag.isValid == true + # check(Bag.getErrors.len == 0) proc checkInvalid() = - newBag invalid: + bag invalid: mypass: tPasswordStrength or "invalid.pass" - check Bag.isValid == false - check(Bag.getErrors.len == 1) - check(Bag.getErrors[0][1] == "invalid.pass") + # check Bag.isValid == false + # check(Bag.getErrors.len == 1) + # check(Bag.getErrors[0][1] == "invalid.pass") checkValid() checkInvalid() \ No newline at end of file