Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #147 from doug-martin/master

v0.4.1
  • Loading branch information...
commit ca15994d92baef4f3885480ea73ecea7ca7e9949 2 parents 2c6d31b + 51fbe1e
@doug-martin doug-martin authored
View
1  .npmignore
@@ -2,3 +2,4 @@ node_modules
nools.iml
.idea
atlassian-ide-plugin.xml
+examples
View
6 docs/History.html
@@ -178,6 +178,12 @@
+<h1>0.4.1</h1>
+<ul>
+<li>Fixed issue with <code>CustomConstraint</code> not binding <code>this.assert</code> to <code>this</code>. <a href="https://github.com/C2FO/nools/pull/146">#146</a> - <a href="https://github.com/raymondfeng">@raymondfeng</a></li>
+<li>Added more tests for custom constraints</li>
+<li>Updated readme to include docs about custom constraints.</li>
+</ul>
<h1>0.4.0</h1>
<ul>
<li>Fix for issue <a href="https://github.com/C2FO/nools/issues/122">#122</a> referencing defined class within another defined class<ul>
View
27 docs/index.html
@@ -216,6 +216,7 @@
<li><a href="#rule-salience">Salience</a></li>
<li><a href="#rule-scope">Scope</a></li>
<li><a href="#constraints">Constraints</a><ul>
+<li><a href="#custom-contraints">Custom</a></li>
<li><a href="#not-constraint">Not</a></li>
<li><a href="#or-constraint">Or</a></li>
<li><a href="#from-constraint">From</a></li>
@@ -1098,6 +1099,32 @@
<li><p>Reference(optional) - An object where the keys are properties on the current object, and values are aliases to use. The alias may be used in succeeding patterns.</p>
</li>
</ol>
+<p><a name="custom-contraints"></a></p>
+<h4>Custom Constraint</h4>
+<p>When declaring your rules progrmmatically you can also use a function as a constraint. The function will be called with an object containing each fact that has matched previous constraints.</p>
+<pre class='prettyprint linenums lang-js'><code class="lang-javascript">var HelloFact = declare({
+ instance: {
+ value: true,
+ constructor: function (value) {
+ this.value = value;
+ }
+ }
+});
+
+var flow = nools.flow(&quot;custom contraint&quot;, function (flow) {
+ flow.rule(&quot;hello rule&quot;, [HelloFact, &quot;h&quot;, function (facts) {
+ return facts.h.value === true;
+ }], function (facts) {
+ console.log(facts.h.value); //always true
+ });
+});
+
+var session = flow.getSession();
+session.assert(new HelloFact(false));
+session.assert(new HelloFact(true));
+session.match().then(function(){
+ console.log(&quot;DONE&quot;);
+});</code></pre>
<p><a name="not-constraint"></a></p>
<h4>Not Constraint</h4>
<p>The <code>not</code> constraint allows you to check that particular <code>fact</code> does <strong>not</strong> exist.</p>
View
4 docs/nools.js
2 additions, 2 deletions not shown
View
6 history.md
@@ -1,3 +1,9 @@
+# 0.4.1
+
+* Fixed issue with `CustomConstraint` not binding `this.assert` to `this`. [#146](https://github.com/C2FO/nools/pull/146) - [@raymondfeng](https://github.com/raymondfeng)
+* Added more tests for custom constraints
+* Updated readme to include docs about custom constraints.
+
# 0.4.0
* Fix for issue [#122](https://github.com/C2FO/nools/issues/122) referencing defined class within another defined class
View
1  nools.js
@@ -983,6 +983,7 @@ Constraint.extend({
this.type = "custom";
this.fn = func;
this.options = options;
+ extd.bindAll(this, ["assert"]);
},
equal: function (constraint) {
View
4 nools.min.js
2 additions, 2 deletions not shown
View
2  package.json
@@ -1,7 +1,7 @@
{
"name": "nools",
"description": "A rules engine for node",
- "version": "0.4.0",
+ "version": "0.4.1",
"bin": {
"nools": "./bin/nools"
},
View
34 readme.md
@@ -38,6 +38,7 @@ Or [download the source](https://raw.github.com/C2FO/nools/master/nools.js) ([mi
* [Salience](#rule-salience)
* [Scope](#rule-scope)
* [Constraints](#constraints)
+ * [Custom](#custom-contraints)
* [Not](#not-constraint)
* [Or](#or-constraint)
* [From](#from-constraint)
@@ -1161,6 +1162,39 @@ when {
4. Reference(optional) - An object where the keys are properties on the current object, and values are aliases to use. The alias may be used in succeeding patterns.
+<a name="custom-contraints"></a>
+
+#### Custom Constraint
+
+When declaring your rules progrmmatically you can also use a function as a constraint. The function will be called with an object containing each fact that has matched previous constraints.
+
+
+```javascript
+var HelloFact = declare({
+ instance: {
+ value: true,
+ constructor: function (value) {
+ this.value = value;
+ }
+ }
+});
+
+var flow = nools.flow("custom contraint", function (flow) {
+ flow.rule("hello rule", [HelloFact, "h", function (facts) {
+ return facts.h.value === true;
+ }], function (facts) {
+ console.log(facts.h.value); //always true
+ });
+});
+
+var session = flow.getSession();
+session.assert(new HelloFact(false));
+session.assert(new HelloFact(true));
+session.match().then(function(){
+ console.log("DONE");
+});
+```
+
<a name="not-constraint"></a>
#### Not Constraint
View
8 test/constraintMatcher.test.js
@@ -497,6 +497,14 @@ it.describe("constraint matcher", function (it) {
assert.equal(atoms[0].type, "reference");
});
+ it.should("return a custom CustomConstraint if called with a function", function(){
+ var atoms = constraintMatcher.toConstraints(function(){
+ return true
+ });
+ assert.lengthOf(atoms, 1);
+ assert.equal(atoms[0].type, "custom");
+ });
+
});
it.describe("#toJs", function (it) {
View
35 test/flow/custom.test.js
@@ -0,0 +1,35 @@
+"use strict";
+var it = require("it"),
+ assert = require("assert"),
+ declare = require("declare.js"),
+ nools = require("../../");
+it.describe("custom contraint rule", function (it) {
+
+ var called = 0;
+ var HelloFact = declare({
+ instance: {
+ value: true,
+ constructor: function (value) {
+ this.value = value;
+ }
+ }
+ });
+
+ var flow = nools.flow("custom contraint", function (flow) {
+ flow.rule("hello rule", [HelloFact, "h", function (facts) {
+ return !!facts.h.value;
+ }], function () {
+ called++;
+ });
+ });
+
+ it.should("call hello world rule", function () {
+ var session = flow.getSession();
+ session.assert(new HelloFact(false));
+ session.assert(new HelloFact(true));
+ return session.match().then(function () {
+ assert.equal(called, 1);
+ });
+ });
+
+});
View
40 test/rules.test.js
@@ -430,34 +430,34 @@ it.describe("Rule", function (it) {
it.describe("custom function as constraints", function (it) {
- var MyConstraint = function(fact) {
- return true;
- };
+ function customContraint(fact) {
+ return true;
+ };
- it.should("create for String function with custom constraint", function() {
- var rule = rules.createRule("My Rule", [String, "s", MyConstraint], cb);
- assert.isNotNull(rule);
- assert.lengthOf(rule, 1);
- rule = rule[0];
- assert.equal(rule.name, "My Rule");
- assert.isNotNull(rule.pattern);
- var pattern = rule.pattern;
- assert.equal(pattern.alias, "s");
- assert.lengthOf(pattern.constraints, 2);
- assert.instanceOf(pattern.constraints[0], constraints.ObjectConstraint);
- assert.equal(pattern.constraints[0].constraint, String);
- assert.instanceOf(pattern.constraints[1], constraints.CustomConstraint);
- assert.strictEqual(rule.cb, cb);
- });
+ it.should("create for String function with custom constraint", function () {
+ var rule = rules.createRule("My Rule", [String, "s", customContraint], cb);
+ assert.isNotNull(rule);
+ assert.lengthOf(rule, 1);
+ rule = rule[0];
+ assert.equal(rule.name, "My Rule");
+ assert.isNotNull(rule.pattern);
+ var pattern = rule.pattern;
+ assert.equal(pattern.alias, "s");
+ assert.lengthOf(pattern.constraints, 2);
+ assert.instanceOf(pattern.constraints[0], constraints.ObjectConstraint);
+ assert.equal(pattern.constraints[0].constraint, String);
+ assert.instanceOf(pattern.constraints[1], constraints.CustomConstraint);
+ assert.strictEqual(rule.cb, cb);
+ });
});
it.describe("custom type via scope", function (it) {
- var MyType = function(name) {
+ var MyType = function (name) {
this.name = name;
};
- it.should("create for String function with custom constraint", function() {
+ it.should("create for String function with custom constraint", function () {
var rule = rules.createRule("My Rule", {scope: {MyType: MyType}}, ['MyType', "s", "s.name === 'X'"], cb);
assert.isNotNull(rule);
assert.lengthOf(rule, 1);
Please sign in to comment.
Something went wrong with that request. Please try again.