- Notifications
You must be signed in to change notification settings - Fork4
Specification design pattern for JavaScript and TypeScript with bonus classes
License
thiagodp/spec-pattern
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Implementation of theSpecification Pattern for JavaScript and TypeScript.
Build complex filters and rules easily.
- No external dependencies.
- Fullytested.
- Usessemantic versioning.Forks are welcome!
$ npm install spec-pattern
import{Between}from'spec-pattern';letrules=newBetween(1,3);console.log(rules.isSatisfiedBy(2));// true
import{Between}from'spec-pattern';letrules=newBetween(1,3).or(newBetween(6,9));console.log(rules.isSatisfiedBy(2));// trueconsole.log(rules.isSatisfiedBy(7));// trueconsole.log(rules.isSatisfiedBy(5));// false
import{Between,In,GreaterThan}from'spec-pattern';letrules=newBetween(1,3).or(newBetween(6,9)).or(newIn([11,25,31])).or(newGreaterThan(50));console.log(rules.isSatisfiedBy(2));// trueconsole.log(rules.isSatisfiedBy(7));// trueconsole.log(rules.isSatisfiedBy(5));// falseconsole.log(rules.isSatisfiedBy(11));// trueconsole.log(rules.isSatisfiedBy(50));// falseconsole.log(rules.isSatisfiedBy(51));// true// Printable !console.log(rules.toString());// (((between (1, 3) or between (6, 9)) or in [11, 25, 31]) or greater than 50)
import{StartsWith,Contains}from'spec-pattern';letrules=newStartsWith('Hello').andNot(newContains('world'));console.log(rules.isSatisfiedBy('Hello Bob'));// trueconsole.log(rules.isSatisfiedBy('Hello world'));// false
import{LengthBetween,EqualTo}from'spec-pattern';letrules=newLengthBetween(2,5).andNot(newEqualTo('Hello'));console.log(rules.isSatisfiedBy(''));// falseconsole.log(rules.isSatisfiedBy('Hi'));// trueconsole.log(rules.isSatisfiedBy('Hello'));// falseconsole.log(rules.isSatisfiedBy('Howdy'));// trueconsole.log(rules.isSatisfiedBy('Hello world'));// false
SameValueAs( value: any ): equality of values, not of types, not of instancesStrictSameValueAs( value: any ): equality of values and types, not of instancesEqualTo( value: any ): equality of values or instances, with==StrictEqualTo( value: any ): equality of values and types or of instances, with===SameTypeAs( value: any ): equality of typesGreaterThan( value: any )GreaterThanOrEqualTo( value: any )LessThan( value: any )LessThanOrEqualTo( value: any )Between( min: any, max: any )In( values: array ): inside an arrayStartsWith( value: string, ignoreCase: boolean = false ): string starts withEndsWith( value: string, ignoreCase: boolean = false ): string ends withContains( value: string, ignoreCase: boolean = false ): string containsLengthBetween( min: any, max: any ): string length between two valuesMatches( regex: RegExp ): matches a regular expression
All these classes extend the abstract classComposite, which in turn implements the interfaceSpec:
interfaceSpec<T>{isSatisfiedBy(candidate:T):boolean;and(other:Spec<T>):Spec<T>;andNot(other:Spec<T>):Spec<T>;or(other:Spec<T>):Spec<T>;orNot(other:Spec<T>):Spec<T>;not():Spec<T>;}
Create your own class by extending theabstract classComposite, like in the following example. Of course, you can also extend one of the aforementioned classes or implement the interfaceSpec(but why reinventing the wheel, right?).
Let's create a classDifferentFrom ...
...in TypeScript:
import{Composite}from'spec-pattern';exportclassDifferentFrom<C,TextendsC|unknown>extendsComposite<C,T>{constructor(private_value:T){super();}isSatisfiedBy(candidate:C|T):boolean{returnthis._value!=candidate;}toString():string{return'different from '+this._value;}}
...or in JavaScript 6+:
import{Composite}from'spec-pattern';classDifferentFromextendsComposite{constructor(value){this.value=value;}isSatisfiedBy(candidate){returnthis.value!=candidate;}toString(){return'different from '+this.value;}}
...or in JavaScript 5+:
varComposite=require('spec-pattern').Composite;functionDifferentFrom(value){Composite.call(this);// super()this.value=value;this.isSatisfiedBy=function(candidate){returnthis.value!=candidate;};this.toString=function(){return'different from '+this.value;};}DifferentFrom.prototype=Object.create(Composite.prototype);DifferentFrom.prototype.constructor=DifferentFrom;
That's it! Just three methods:constructor,isSatisfiedBy, andtoString().
About
Specification design pattern for JavaScript and TypeScript with bonus classes
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.