From ca59678a2c78550b45f988648a8acb2257717ea0 Mon Sep 17 00:00:00 2001 From: Frank Thelen Date: Sat, 6 Jan 2018 13:04:48 +0100 Subject: [PATCH] unit tests on `Delegator` and `observe` --- README.md | 13 +++++----- package.json | 1 + test/delegate.spec.js | 21 +++++++++++++++++ test/observe.spec.js | 55 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 test/delegate.spec.js create mode 100644 test/observe.spec.js diff --git a/README.md b/README.md index 125ccf2..ab37a03 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,11 @@ This is a small rule engine for Node. [![License Status](http://img.shields.io/npm/l/rools.svg)]() *Primary goal* was to provide a nice and state-of-the-art interface for modern JavaScript (ES6). -Facts are plain JavaScript or JSON objects or objects from ES6 classes with getters and setters. -Rules are specified in pure JavaScript rather than in a separate, special-purpose language like DSL. +*Facts* are plain JavaScript or JSON objects or objects from ES6 classes with getters and setters. +*Rules* are specified in pure JavaScript rather than in a separate, special-purpose language like DSL. *Secondary goal* was to provide [RETE](https://en.wikipedia.org/wiki/Rete_algorithm)-like efficiency and optimization. -*1.0.0-beta* is feature-complete and stable. - ## Install ```bash @@ -93,7 +91,7 @@ Both are JavaScript functions, i.e., classic functions or ES6 arrow functions. Actions can also be asynchronous. Rules access the facts in both, premises (`when`) and actions (`then`). -The can access properties directly, e.g., `facts.user.salery`, +They can access properties directly, e.g., `facts.user.salery`, or through getters and getters if applicable, e.g., `facts.user.getSalery()`. ### Conflict resolution @@ -362,7 +360,9 @@ This can be configured like this. const delegate = ({ message, rule, error }) => { console.error(message, rule, error); }; -const rools = new Rools({ logging: { error: true, debug: false, delegate } }); +const rools = new Rools({ + logging: { error: true, debug: false, delegate }, +}); ... ``` @@ -373,4 +373,3 @@ Some of the features for future releases are: * Activation groups * Agenda groups * Extend rules - * More unit tests diff --git a/package.json b/package.json index 0d88174..9461970 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "rule", "engine", "rools", + "rule engine", "rules engine" ], "scripts": { diff --git a/test/delegate.spec.js b/test/delegate.spec.js new file mode 100644 index 0000000..396243a --- /dev/null +++ b/test/delegate.spec.js @@ -0,0 +1,21 @@ +const Delegator = require('../src/Delegator'); +require('./setup'); + +describe('Delegator', () => { + it('should delegate call', () => { + const delegator = new Delegator(); + const spy = sinon.spy(); + delegator.set(spy); + delegator.delegate('bla'); + expect(spy.calledWith('bla')).to.be.equal(true); + }); + + it('should not delegate call if unset', () => { + const delegator = new Delegator(); + const spy = sinon.spy(); + delegator.set(spy); + delegator.unset(); + delegator.delegate('bla'); + expect(spy.called).to.be.equal(false); + }); +}); diff --git a/test/observe.spec.js b/test/observe.spec.js new file mode 100644 index 0000000..87a9d52 --- /dev/null +++ b/test/observe.spec.js @@ -0,0 +1,55 @@ +const observe = require('../src/observe'); +require('./setup'); + +const object = { + prop: true, + sub: { + subsub: { + bla: true, + }, + }, +}; + +describe('observe', () => { + it('should notify on reading property', () => { + const spy = sinon.spy(); + const proxy = observe(object, spy); + const temp = proxy.prop; // eslint-disable-line no-unused-vars + expect(spy.calledWith('prop')).to.be.equal(true); + }); + + it('should notify on writing property', () => { + const spy = sinon.spy(); + const proxy = observe(object, spy); + proxy.prop = false; + expect(spy.calledWith('prop')).to.be.equal(true); + }); + + it('should notify on deleting property', () => { + const spy = sinon.spy(); + const proxy = observe(object, spy); + delete proxy.prop; + expect(spy.calledWith('prop')).to.be.equal(true); + }); + + it('should notify on reading sub-property', () => { + const spy = sinon.spy(); + const proxy = observe(object, spy); + const temp = proxy.sub.subsub.bla; // eslint-disable-line no-unused-vars + expect(spy.calledWith('sub')).to.be.equal(true); + }); + + it('should notify on writing sub-property', () => { + const spy = sinon.spy(); + const proxy = observe(object, spy); + proxy.sub.subsub.bla = false; + expect(spy.calledWith('sub')).to.be.equal(true); + }); + + it('should notify on deleting sub-property', () => { + const spy = sinon.spy(); + const proxy = observe(object, spy); + delete proxy.sub.subsub.bla; + expect(spy.calledWith('sub')).to.be.equal(true); + }); +});