All Versions
Latest Version
Avg Release Cycle
36 days
Latest Release
954 days ago

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

    ๐Ÿ›  Fixed and improved

    • 870dd86 fix: notEquals typings (ealush)
    • d7db9c3 patch: extract business logic out of context module (#382) (ealush)
    • 765dea2 fix: get/reset suite typings (gaspoute)
  • v2.2.0 Changes

    September 08, 2020

    vest: [2.2.0] - 2020-09-08

    โž• Added

    ๐Ÿ›  Fixed and improved

  • v2.1.0 Changes

    August 09, 2020

    vest: [2.1.0] - 2020-08-09

    โž• Added

    • d1ce227 minor: add and (#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 (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 (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 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.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(;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


    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 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"


    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


    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

    ๐Ÿ— npm version Build Status

    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([^@]+@[^\.]+\..+/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.