/vest

Vest ✅ Declarative validations framework

Primary LanguageJavaScriptMIT LicenseMIT

Vest

Vest 🦺 Declarative Validation Testing

Github Stars Npm downloads

npm version Build Status Known Vulnerabilities minifiedSize

Join discord

Tutorials

Step By Step React Tutorial

🦺 What is Vest?

Vest is a validations library for JS apps that derives its syntax from modern JS unit testing frameworks such as Mocha or Jest. It is easy to learn due to its use of already common declarative patterns. It works great with user-input validation and with validating upon user interaction to provide the best possible user experience.

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.

Using Vest for form validation can reduce bloat, improve feature readability and maintainability.

Basic Example full

Memoized async test memo

✅ Motivation

Writing forms is an integral part of building web apps, and even though it may seem trivial at first - as your feature grows over time, so does your validation logic grows in complexity.

Vest tries to remediate this by separating validation logic from feature logic so it is easier to maintain over time and refactor when needed.

✨ Vest's features

  • 🎨 Framework agnostic (BYOUI)
  • ⚡️ Rich, extendable, assertions library (enforce) (doc)
  • 🚥 Multiple validations for the same field
  • ⚠️ Warning (non failing) tests (doc)
  • 📝 Validate only the fields the user interacted with (doc)
  • ⏳ Memoize async validations to reduce calls to the server (doc)
  • 🚦 Test grouping (doc)

Example code (Run in sandbox)

import vest, { test } from 'vest';
import enforce from 'vest/enforceExtended';

export default vest.create('user_form', (data = {}, currentField) => {
  vest.only(currentField);

  test('username', 'Username is required', () => {
    enforce(data.username).isNotEmpty();
  });

  test('username', 'Username is too short', () => {
    enforce(data.username).longerThanOrEquals(3);
  });

  test('password', 'Password is required', () => {
    enforce(data.password).isNotEmpty();
  });

  test('password', 'Password must be at least 6 chars long', () => {
    enforce(data.password).longerThanOrEquals(6);
  });

  test('password', 'Password is weak, Maybe add a number?', () => {
    vest.warn();
    enforce(data.password).matches(/[0-9]/);
  });

  if (data.password) {
    test('confirm_password', 'Passwords do not match', () => {
      enforce(data.confirm_password).equals(data.password);
    });
  }

  test('email', 'Email Address is not valid', () => {
    enforce(data.email).isEmail();
  });

  test('tos', () => {
    enforce(data.tos).isTruthy();
  });
});

Why Vest?

  • 🧠 Vest is really easy to learn. You can 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 simple 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.

Vest is an evolution of Passable by Fiverr.