<commit_before># ![bspec logo](http://i.imgur.com/5zhNRSp.png)

[![Build Status](https://travis-ci.org/gchudnov/bspec.svg)](https://travis-ci.org/gchudnov/bspec) [![Coverage Status](https://coveralls.io/repos/gchudnov/bspec/badge.svg)](https://coveralls.io/r/gchudnov/bspec)

[![Sauce Test Status](https://saucelabs.com/browser-matrix/bspec.svg)](https://saucelabs.com/u/bspec)

> A JavaScript library for structuring business rules.

## Overview

[Structuring and validating business rules in JavaScript](https://medium.com/@gchudnov/structuring-and-validating-business-rules-in-javascript-fbaa1019902a)

## Example

Consider the following scenario:

On entering a train station, passengers are required to insert a ticket into a slot beside a closed barrier. An entry barrier opens only if the ticket meets all of the following criteria:

1. it is valid for travel from that station;
2. it has not expired;
3. it has not already been used for the maximum number of journeys allowed.

```javascript
'use strict';

// use promise-based specifications
var Spec = require('bspec').PromiseSpec;

// hardcore the `today` date for the sake of consistent results
var TODAY = new Date(2015, 2, 1);

// Is the ticket expired?
var isTicketExpired = function isTicketExpired(ticket) {
  return Promise.resolve(TODAY > ticket.expires_at);
};

// Is the ticket has been used for the maximum number of journeys allowed?
var isMaxJourneys = function isMaxJourneys(ticket) {
  return Promise.resolve(ticket.cur_journeys >= ticket.max_journeys);
};

// Is the ticket valid for travel from `name` station?
var isValidFromStation = function isValidFromStation(name, ticket) {
  return Promise.resolve(ticket.stations.indexOf(name) !== -1);
};

// Rule implementation for the `Riva` station barrier<commit_msg>Tiny typo fix<commit_after># ![bspec logo](http://i.imgur.com/5zhNRSp.png)

[![Build Status](https://travis-ci.org/gchudnov/bspec.svg)](https://travis-ci.org/gchudnov/bspec) [![Coverage Status](https://coveralls.io/repos/gchudnov/bspec/badge.svg)](https://coveralls.io/r/gchudnov/bspec)

[![Sauce Test Status](https://saucelabs.com/browser-matrix/bspec.svg)](https://saucelabs.com/u/bspec)

> A JavaScript library for structuring business rules.

## Overview

[Structuring and validating business rules in JavaScript](https://medium.com/@gchudnov/structuring-and-validating-business-rules-in-javascript-fbaa1019902a)

## Example

Consider the following scenario:

On entering a train station, passengers are required to insert a ticket into a slot beside a closed barrier. An entry barrier opens only if the ticket meets all of the following criteria:

1. it is valid for travel from that station;
2. it has not expired;
3. it has not already been used for the maximum number of journeys allowed.

```javascript
'use strict';

// use promise-based specifications
var Spec = require('bspec').PromiseSpec;

// hardcode the `today` date for the sake of consistent results
var TODAY = new Date(2015, 2, 1);

// Is the ticket expired?
var isTicketExpired = function isTicketExpired(ticket) {
  return Promise.resolve(TODAY > ticket.expires_at);
};

// Is the ticket has been used for the maximum number of journeys allowed?
var isMaxJourneys = function isMaxJourneys(ticket) {
  return Promise.resolve(ticket.cur_journeys >= ticket.max_journeys);
};

// Is the ticket valid for travel from `name` station?
var isValidFromStation = function isValidFromStation(name, ticket) {
  return Promise.resolve(ticket.stations.indexOf(name) !== -1);
};

// Rule implementation for the `Riva` station barrier
{'fraction_non_alphanumeric': 0.11613623673925182, 'fraction_numerical': 0.010050251256281407, 'mean_word_length': 4.9223140495867765, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 14, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '999960', 'n_tokens_mistral': 1147, 'n_tokens_neox': 1083, 'n_words': 343}