Releases: ealush/vest
vest: [3.1.2] - 2021-01-30
vest: [3.1.1] - 2021-01-21
vest: [3.1.0] - 2021-01-21
vest: [3.0.2] - 2021-01-20
Fixed and improved
- 736001f fix: custom enforce rules typings (ealush)
vest: [3.0.1] - 2021-01-20
Fixed and improved
- f59a659 fix: error message override when no warnings (ealush)
vest: [3.0.0] - 2021-01-08
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)
n4s: [3.0.0] - 2021-01-08
Changed or removed
- bbe0159 breaking: Remove ensure export as it is now replaced by the lazy enforce interface (#497) (Evyatar)
Added
- 2f948fc feat: deeply nested schema result (#555) (Evyatar)
- c2ea710 added: allOf compound rule (#533) (Moses3301)
- db7f6f4 added: oneOf compound (#526) (hpsharon)
- 54e500f feature: templates (#509) (Evyatar)
- c0053f2 added: anyOf for either/or style enforcements #269 (#493) (Alex Kaplan)
- 670887d added: isArrayOf rule #488 (#499) (Moses3301)
- 7df6371 added: rule: isBoolean (#494) (Evyatar)
- f3ff232 minor: Add shape validator (#491) (Evyatar)
- 3e33fa8 added: lazy evaluated enforcements (#479) (Evyatar)
- a54e455 added: isNegative & isPositive (#433) (Ganesh Patil)
- eecb59a feat: rule isBetween and isNotBetween (#419) (Daniel Hermon)
- 17f74e1 added: startsWith rule (#414) (Daniel Hermon)
- d77d569 added: endsWith and doesNotEndWith rules (#409) (Daniel Hermon)
- a424282 added:
isNull
rule. (#404) (omri lugasi) - a13e860 added: isUndefined rule(#410) (omri lugasi)
Fixed and improved
vest: [2.2.3] - 2020-09-16
vest: [2.2.0] - 2020-09-08
Vest: [2.1.0] - 2020-08-09
vest: [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
Vest version 2 Release notes
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 a validate
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()
or vest.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.js
import vest from 'vest';
const validate = vest.create('car_purchase', callback);
// file_2.js
import 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 general
res.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 return false
, and by that logic, you might mistakenly add a is-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 yet
tested: 'some-tested-class', // will only be applied if the provided field did run
invalid: 'my_invalid_class', // will only be applied if the provided field ran at least once and has an errror
warning: '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('example@gmail.com').isEmail();