Skip to content

Commit ca15994

Browse files
committed
Merge pull request #147 from doug-martin/master
v0.4.1
2 parents 2c6d31b + 51fbe1e commit ca15994

File tree

12 files changed

+143
-25
lines changed

12 files changed

+143
-25
lines changed

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules
22
nools.iml
33
.idea
44
atlassian-ide-plugin.xml
5+
examples

docs/History.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,12 @@
178178

179179

180180

181+
<h1>0.4.1</h1>
182+
<ul>
183+
<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>
184+
<li>Added more tests for custom constraints</li>
185+
<li>Updated readme to include docs about custom constraints.</li>
186+
</ul>
181187
<h1>0.4.0</h1>
182188
<ul>
183189
<li>Fix for issue <a href="https://github.com/C2FO/nools/issues/122">#122</a> referencing defined class within another defined class<ul>

docs/index.html

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ <h1>Usage</h1>
216216
<li><a href="#rule-salience">Salience</a></li>
217217
<li><a href="#rule-scope">Scope</a></li>
218218
<li><a href="#constraints">Constraints</a><ul>
219+
<li><a href="#custom-contraints">Custom</a></li>
219220
<li><a href="#not-constraint">Not</a></li>
220221
<li><a href="#or-constraint">Or</a></li>
221222
<li><a href="#from-constraint">From</a></li>
@@ -1098,6 +1099,32 @@ <h3>Constraints</h3>
10981099
<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>
10991100
</li>
11001101
</ol>
1102+
<p><a name="custom-contraints"></a></p>
1103+
<h4>Custom Constraint</h4>
1104+
<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>
1105+
<pre class='prettyprint linenums lang-js'><code class="lang-javascript">var HelloFact = declare({
1106+
instance: {
1107+
value: true,
1108+
constructor: function (value) {
1109+
this.value = value;
1110+
}
1111+
}
1112+
});
1113+
1114+
var flow = nools.flow(&quot;custom contraint&quot;, function (flow) {
1115+
flow.rule(&quot;hello rule&quot;, [HelloFact, &quot;h&quot;, function (facts) {
1116+
return facts.h.value === true;
1117+
}], function (facts) {
1118+
console.log(facts.h.value); //always true
1119+
});
1120+
});
1121+
1122+
var session = flow.getSession();
1123+
session.assert(new HelloFact(false));
1124+
session.assert(new HelloFact(true));
1125+
session.match().then(function(){
1126+
console.log(&quot;DONE&quot;);
1127+
});</code></pre>
11011128
<p><a name="not-constraint"></a></p>
11021129
<h4>Not Constraint</h4>
11031130
<p>The <code>not</code> constraint allows you to check that particular <code>fact</code> does <strong>not</strong> exist.</p>

docs/nools.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

history.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# 0.4.1
2+
3+
* Fixed issue with `CustomConstraint` not binding `this.assert` to `this`. [#146](https://github.com/C2FO/nools/pull/146) - [@raymondfeng](https://github.com/raymondfeng)
4+
* Added more tests for custom constraints
5+
* Updated readme to include docs about custom constraints.
6+
17
# 0.4.0
28

39
* Fix for issue [#122](https://github.com/C2FO/nools/issues/122) referencing defined class within another defined class

nools.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,7 @@ Constraint.extend({
983983
this.type = "custom";
984984
this.fn = func;
985985
this.options = options;
986+
extd.bindAll(this, ["assert"]);
986987
},
987988

988989
equal: function (constraint) {

nools.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "nools",
33
"description": "A rules engine for node",
4-
"version": "0.4.0",
4+
"version": "0.4.1",
55
"bin": {
66
"nools": "./bin/nools"
77
},

readme.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Or [download the source](https://raw.github.com/C2FO/nools/master/nools.js) ([mi
3838
* [Salience](#rule-salience)
3939
* [Scope](#rule-scope)
4040
* [Constraints](#constraints)
41+
* [Custom](#custom-contraints)
4142
* [Not](#not-constraint)
4243
* [Or](#or-constraint)
4344
* [From](#from-constraint)
@@ -1161,6 +1162,39 @@ when {
11611162

11621163
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.
11631164

1165+
<a name="custom-contraints"></a>
1166+
1167+
#### Custom Constraint
1168+
1169+
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.
1170+
1171+
1172+
```javascript
1173+
var HelloFact = declare({
1174+
instance: {
1175+
value: true,
1176+
constructor: function (value) {
1177+
this.value = value;
1178+
}
1179+
}
1180+
});
1181+
1182+
var flow = nools.flow("custom contraint", function (flow) {
1183+
flow.rule("hello rule", [HelloFact, "h", function (facts) {
1184+
return facts.h.value === true;
1185+
}], function (facts) {
1186+
console.log(facts.h.value); //always true
1187+
});
1188+
});
1189+
1190+
var session = flow.getSession();
1191+
session.assert(new HelloFact(false));
1192+
session.assert(new HelloFact(true));
1193+
session.match().then(function(){
1194+
console.log("DONE");
1195+
});
1196+
```
1197+
11641198
<a name="not-constraint"></a>
11651199
#### Not Constraint
11661200

test/constraintMatcher.test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,14 @@ it.describe("constraint matcher", function (it) {
497497
assert.equal(atoms[0].type, "reference");
498498
});
499499

500+
it.should("return a custom CustomConstraint if called with a function", function(){
501+
var atoms = constraintMatcher.toConstraints(function(){
502+
return true
503+
});
504+
assert.lengthOf(atoms, 1);
505+
assert.equal(atoms[0].type, "custom");
506+
});
507+
500508
});
501509

502510
it.describe("#toJs", function (it) {

test/flow/custom.test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"use strict";
2+
var it = require("it"),
3+
assert = require("assert"),
4+
declare = require("declare.js"),
5+
nools = require("../../");
6+
it.describe("custom contraint rule", function (it) {
7+
8+
var called = 0;
9+
var HelloFact = declare({
10+
instance: {
11+
value: true,
12+
constructor: function (value) {
13+
this.value = value;
14+
}
15+
}
16+
});
17+
18+
var flow = nools.flow("custom contraint", function (flow) {
19+
flow.rule("hello rule", [HelloFact, "h", function (facts) {
20+
return !!facts.h.value;
21+
}], function () {
22+
called++;
23+
});
24+
});
25+
26+
it.should("call hello world rule", function () {
27+
var session = flow.getSession();
28+
session.assert(new HelloFact(false));
29+
session.assert(new HelloFact(true));
30+
return session.match().then(function () {
31+
assert.equal(called, 1);
32+
});
33+
});
34+
35+
});

test/rules.test.js

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -430,34 +430,34 @@ it.describe("Rule", function (it) {
430430

431431
it.describe("custom function as constraints", function (it) {
432432

433-
var MyConstraint = function(fact) {
434-
return true;
435-
};
433+
function customContraint(fact) {
434+
return true;
435+
};
436436

437-
it.should("create for String function with custom constraint", function() {
438-
var rule = rules.createRule("My Rule", [String, "s", MyConstraint], cb);
439-
assert.isNotNull(rule);
440-
assert.lengthOf(rule, 1);
441-
rule = rule[0];
442-
assert.equal(rule.name, "My Rule");
443-
assert.isNotNull(rule.pattern);
444-
var pattern = rule.pattern;
445-
assert.equal(pattern.alias, "s");
446-
assert.lengthOf(pattern.constraints, 2);
447-
assert.instanceOf(pattern.constraints[0], constraints.ObjectConstraint);
448-
assert.equal(pattern.constraints[0].constraint, String);
449-
assert.instanceOf(pattern.constraints[1], constraints.CustomConstraint);
450-
assert.strictEqual(rule.cb, cb);
451-
});
437+
it.should("create for String function with custom constraint", function () {
438+
var rule = rules.createRule("My Rule", [String, "s", customContraint], cb);
439+
assert.isNotNull(rule);
440+
assert.lengthOf(rule, 1);
441+
rule = rule[0];
442+
assert.equal(rule.name, "My Rule");
443+
assert.isNotNull(rule.pattern);
444+
var pattern = rule.pattern;
445+
assert.equal(pattern.alias, "s");
446+
assert.lengthOf(pattern.constraints, 2);
447+
assert.instanceOf(pattern.constraints[0], constraints.ObjectConstraint);
448+
assert.equal(pattern.constraints[0].constraint, String);
449+
assert.instanceOf(pattern.constraints[1], constraints.CustomConstraint);
450+
assert.strictEqual(rule.cb, cb);
451+
});
452452
});
453453

454454
it.describe("custom type via scope", function (it) {
455455

456-
var MyType = function(name) {
456+
var MyType = function (name) {
457457
this.name = name;
458458
};
459459

460-
it.should("create for String function with custom constraint", function() {
460+
it.should("create for String function with custom constraint", function () {
461461
var rule = rules.createRule("My Rule", {scope: {MyType: MyType}}, ['MyType', "s", "s.name === 'X'"], cb);
462462
assert.isNotNull(rule);
463463
assert.lengthOf(rule, 1);

0 commit comments

Comments
 (0)