Changelog History
Page 2
-
v3.1.0 Changes
January 21, 2021โ Added
- ๐ 8458837 minor: support schema skip and only (#557) (Evyatar)
- โ 0cf5615 minor: support custom message in test (#560) (Evyatar)
-
v3.0.2 Changes
January 20, 2021๐ Fixed and improved
- 736001f fix: custom enforce rules typings (ealush)
-
v3.0.0 Changes
January 08, 2021๐ Changed or removed
- ๐ 3d47fb1 breaking: remove vest.draft() (#474) (Evyatar)
- ๐ 0ef8ec8 breaking: remove validate (ealush)
- ๐ 00a5aba breaking: remove global state reference (ealush)
โ Added
- ๐ b8746f9 feat: suite.remove (ealush)
- โ 4dd6a30 feat: test.each (#541) (Alex Kaplan)
- ๐ 4c81bc0 added: enforce.loose for loose shape enforcement style #492 (#505) (Alex Kaplan)
- ๐ 8e3386b Added: Chaining support in lazy enforcement (#495) (Evyatar)
๐ Fixed and improved
- โ ede4587 test: add tests for VestTest.cancel (ealush)
- f3bb418 patch: optionalFunctionValue utility (ealush)
- 81f3a4d fix: retain lagging list after reset (ealush)
- โ 61d6258 tests: improve rule test fixture (ealush)
- โ 8d0b087 tests: runLazyRule (ealush)
- 0006059 patch: reduce transpiled bundle size (#522) (Evyatar)
- โก๏ธ 52691b0 patch: update dev mode errors (ealush)
- ๐ c3949bd patch: improve enforcement performance on legacy browsers (#507) (Evyatar)
- 3083ba4 patch: use rules for internal comparisons (ealush)
- ๐ฆ 26d6bed patch: move anyone package inside (#502) (Evyatar)
- 56b195d patch: use isPromise utility (#501) (Evyatar)
- eb43009 patch: use enforce rules for internal evaluations (ealush)
- ๐ b8c8b6c patch: move severity profile logic out (#496) (Evyatar)
- 458bccd readme: add a discord invite link (Evyatar)
- c3e4449 patch: sort out organize deps (ealush)
- 797fe4e patch: reduce built size (#465) (Evyatar)
- 92924df fix: use proxy with ensure (ealush)
- 1d6955d patch: simplify conditions (ealush)
- ๐ c6b36f2 patch: remove state init symbol (ealush)
- ๐ 4dd0132 patch: Move state modules to the same directory (ealush)
- ๐ 65a7468 patch: Remove state history (ealush)
- 699b293 use context.bind (ealush)
- b080130 patch: rewrite state module (ealush)
- ๐ e5eac8f patch: remove context around async test (ealush)
- 9de029c patch: simplify cache (ealush)
- ๐ 1474825 test: remove runSpec module (ealush)
- 1a69910 types: isUndefined rule (ealush)
- b20aa66 patch: regorganize Context and Suite State (#413) (Evyatar)
- โ๏ธ ca5dda1 fix: README typos (#392) (baahrens)
-
v2.2.3 Changes
September 16, 2020 -
v2.1.0 Changes
August 09, 2020vest: [2.1.0] - 2020-08-09
โ Added
- d1ce227 minor: add vest.skip.group and vest.only.group (#225) (ealush)
- โ 19e592e added: test.memo for memoized tests (#238) (ealush)
- e6cccc9 added: returned function name is the name of the suite (ealush)
- f9f1d39 added: promisify utility (#261) (adife)
๐ Fixed and improved
- โช ba6ca3d fix: make vest.reset restore initial state (#235) (ealush)
- ๐ a657058 patch: cache validation result for improved runtime performance (#237) (ealush)
- 96210af Skip cache when resolving done results (#240) (ealush)
- c2beec9 fix: edge case when calling done after delay (#252) (ealush)
- 2582c43 types: group and skip types (#258) (ealush)
- a215c43 patch: return enforce from extend api (ealush)
- โ bb6cc1d fix: added safeguard to async test inference (#266) (ealush)
- โก๏ธ ff5608f Update README.md (ealush)
- ๐ 553c8fe patch: Move exclusion to context (#274) (ealush)
- 4f24697 patch: Replace global object with closures (#275) (ealush)
- โ a3bc606 patch: clean runAsyncTest done callback (ealush)
- โก๏ธ 4d3b583 Update README.md (ealush)
- โ 32ea43f Use latest branch (ealush)
- โ 51e7aa2 patch: Skip iteration of pending tests (#294) (ealush)
n4s: [2.1.0] - 2020-08-09
โ Added
-
v2.0.0 Changes
June 20, 2020๐ Support stateful validations
โ Vest 2 introduces a big architectural change with the addition of internal state. A new api
vest.create('suite_name', testsCallback)
initializes a new suite and returns avalidate
function.const validate = vest.create('suite\_name', () =\> {test('fieldName', 'message', () =\> {/\* ... \*/});})
๐ This internal state is very handy and reduces consumer side boilerplate code, because it merges previously-run partial validation results, meaning that if you use the
vest.only()
orvest.skip()
hooks to only run certain fields, vest will merge your previous validation results with the fields skipped in the current run.๐ In previous versions, you had to do that yourself and merge it in your app's state.
โ This state feature also allows auto-cancellation of outdated async callbacks - if you run your async validation again before a previous run did not finish, vest will internally check which async call did not finish yet - and only call the callbacks from the last run. If those async validations belong to a field that's skipped in the most recent validation, then the test won't be ignored (because it has no newer callback).
โ The stateful
validate
function now takes params and passes it to your validation tests:const validate = vest.create('suite\_name', (data) =\> {test('fieldName', 'message', () =\> {/\* ... \*/});});validate({ username: 'lexapem' })
๐ New vest hook: vest.get()
Since vest is now stateful, it means that it can allow you to access your state validation out of context - from a different component, from example - without having to store it in a higher up state.
// file\_1.jsimport vest from 'vest';const validate = vest.create('car\_purchase', callback);// file\_2.jsimport vest from 'vest';const result = vest.get('car\_purchase');result.hasErrors()
โ Added support for nesting tests within a group
๐ Vest now supports adding another level of nesting to your validations with groups. They allow you to skip/only full blocks from your validation based on your logic - such as current tab, or some userland condition.
๐ The benefit of group (over general if/else) is that when skipped - they will also be merged from previous state.
import vest, { test, group, enforce } from 'vest';vest.create('authentication\_form', data =\> {vest.skip(data.userExists ? 'signUp' : 'signIn');test('userName', "Can't be empty", () =\> {enforce(data.username).isNotEmpty();});test('password', "Can't be empty", () =\> {enforce(data.password).isNotEmpty();});group('signIn', () =\> {test('userName','User not found. Please check if you typed it correctly.',findUserName(data.username));});group('signUp', () =\> {test('email', 'Email already registered', isEmailRegistered(data.email));test('age', 'You must be at least 18 years old to join', () =\> {enforce(data.age).largerThanOrEquals(18);});});});
๐ Changes related to the introduction of groups
- ๐ New result object methods:
โ getErrorsByGroup, getWarningsByGroup, hasErrorsByGroup, hasWarningsByGroup
res.hasErrorsByGroup('groupName') // checks the group in generalres.hasErrorsByGroup('groupName', 'fieldName') // check a given field in the group
๐ New Vest utilities
classNames
After validating user input, you usually need to also indicate the validation result on the page - most of the times by adding a class to your input element. One of the difficulties you are likely to face is that the logic for setting the class is not always the negation of
hasErrors
.const addIsValidClass = !res.hasErrors('fieldName'); // this does not ALWAYS mean 'valid'
What about when the field is skipped or not validated yet? It does not have errors, so
res.hasErrors('fieldName')
will returnfalse
, and by that logic, you might mistakenly add ais-valid
class to your element.โ In this case you will also need to check if the test actually ran - so:
const addIsValidClass = res.tests[fieldName] && !res.hasErrors('fieldName');
โ But this can get pretty cumbersome when added to multiple fields with different criteria (untested, invalid, hasWarning...).
This is what
vest/classNames
is for. It is a tiny utility function, that allows you to specify classnames to be added for each criteria.โ The way it works is simple. You call
classNames
with your result object, and the list of classes you want to be added for whenever the field is tested, untested, has warning or is invalid. It then returns a function that when called with a field name, returns a space delimited string of classes. If more than one class applies (both tested and invalid, for example) they will both be added to the string.import classNames from 'vest/classNames';import validate from './validation';const res = validate(data);const cn = classNames(res, {untested: 'is-untested', // will only be applied if the provided field did not run yettested: 'some-tested-class', // will only be applied if the provided field did runinvalid: 'my\_invalid\_class', // will only be applied if the provided field ran at least once and has an errrorwarning: 'my\_warning\_class', // will only be applied if the provided field ran at least once and has a warning});const fieldOneClasses = cn('field\_1'); // "is-untested"const fieldTwoClasses = cn('field\_2'); // "some-tested-class my\_invalid\_class"const fieldThreeClasses = cn('field\_3'); // "some-tested-class my\_warning\_class"
enforceExtended
Along with the existing rules, you might need different business related rules, for email, phone number, credit card validations, and more.
Business related validations provided with enforceExtended
- isAlphanumeric
- isCreditCard
- isCurrency
- isEmail
- isIP
- isIdentityCard
- isJSON
- isLocale
- isMimeType
- isMobilePhone
- isPassportNumber
- isPostalCode
- isURL
Usage:
import enforce from 'vest/enforceExtended';enforce('[email protected]').isEmail();
-
v1.0.10 Changes
May 07, 2020โ Added
- 3c17e85 added: runWithContext interface (ealush)
๐ Fixed and improved
- 0๏ธโฃ 1d1871b fix: use default values when field not found in output methods (ealush)
- ๐ 89aaeff fix: Temporarily remove ts typings (ealush)
-
v1.0.9
April 14, 2020 -
v1.0.0 Changes
December 22, 2019โ Vest - Validation Testing
- ๐ Documentation homepage
- Try vest live
What is Vest?
Vest is a validations library for JS apps that derives its syntax from modern JS frameworks such as Mocha or Jest. It is easy to learn due to its use of already common declarative patterns.
The idea behind Vest is that your validations can be described as a 'spec' or a contract that reflects your form or feature structure. Your validations run in production, and they are framework agnostic - meaning Vest works well with React, Angular, Vue, or even without a framework at all.
Example code:
// validation.jsimport { validate, test, enforce } from 'vest';const validation = (data) =\> validate('NewUserForm', () =\> {test('username', 'Must be at least 3 chars', () =\> {enforce(data.username).longerThanOrEquals(3);});test('email', 'Is not a valid email address', () =\> {enforce(data.email).isNotEmpty().matches(/[^@]+@[^\.]+\..+/g);});});export default validation; // myFeature.jsimport validation from './validation.js';const res = validation({username: 'example',email: '[email protected]'});res.hasErrors() // returns whether the form has errorsres.hasErrors('username') // returns whether the 'username' field has errorsres.getErrors() // returns an object with an array of errors per fieldres.getErrors('username') // returns an array of errors for the `username` field
Why Vest?
- โ Vest is really easy to learn, and you can easily take your existing knowledge of unit tests and transfer it to validations.
- Vest takes into account user interaction and warn only validations.
- Your validations are structured, making it very easy to read and write. All validation files look the same.
- Your validation logic is separate from your feature logic, preventing the spaghetti code that's usually involved with writing validations.
- Validation logic is easy to share and reuse across features.
- If your backend is node, you can use the same Vest modules for both client-side and server-side validations.
Vest is a continuation of Passable by Fiverr.