Permalink
Browse files

Added events for flow session

  * assert [Fact] - emitted when a fact is asserted
  * retract [Fact] - emitted when a fact is retracted
  * modify[Fact] - emitted when a fact is modified
  * fire[name, factHash] - emitted when a rule is fired
  • Loading branch information...
1 parent 1a87a1e commit 838e464a5a3a79343110dafa078d487d40734b6d @doug-martin doug-martin committed May 16, 2012
Showing with 87 additions and 2 deletions.
  1. +1 −1 lib/compile.js
  2. +6 −1 lib/index.js
  3. +55 −0 test/flow.test.js
  4. +25 −0 test/rules/simple.nools
View
@@ -50,7 +50,7 @@
throw new Error("no rules defined for rule " + name);
}
var action = obj.action;
- if (!action) {
+ if (comb.isUndefined(action)) {
throw new Error("No action was defined for rule " + name);
}
var conditions = [], identifiers = [];
View
@@ -3,6 +3,7 @@
var comb = require("comb"),
when = comb.when,
nodes = require("./nodes"),
+ EventEmitter = require("events").EventEmitter,
rule = require("./rule"),
AVLTree = comb.collections.AVLTree,
wm = require("./workingMemory"),
@@ -154,7 +155,7 @@
});
- var Flow = comb.define(null, {
+ var Flow = comb.define(EventEmitter, {
instance:{
@@ -179,6 +180,7 @@
assert:function (fact) {
this.__wmAltered = true;
this.__factHelper(fact, true);
+ this.emit("assert", fact);
return fact;
},
@@ -187,6 +189,7 @@
//fact = this.workingMemory.getFact(fact);
this.__wmAltered = true;
this.__factHelper(fact, false);
+ this.emit("retract", fact);
return fact;
},
@@ -198,6 +201,7 @@
if ("function" === typeof cb) {
cb.call(fact, fact);
}
+ this.emit("modify", fact);
return this.assert(fact);
},
@@ -222,6 +226,7 @@
if (!agenda.isEmpty()) {
var activation = agenda.pop();
activation.used = true;
+ flow.emit("fire", activation.rule.name, activation.match.factHash);
when(activation.rule.fire(flow, activation.match), function () {
if (flow.__wmAltered) {
rootNode.incrementCounter();
View
@@ -160,6 +160,61 @@
});
+ it.describe("events", function(it){
+ var flow = nools.compile(__dirname + "/rules/simple.nools"),
+ Message = flow.getDefined("Message"),
+ session;
+
+ it.beforeEach(function(){
+ session = flow.getSession();
+ });
+
+ it.should("emit when facts are asserted", function(next){
+ var m = new Message("hello");
+ session.once("assert", function(fact){
+ assert.deepEqual(fact, m);
+ next();
+ });
+ session.assert(m);
+ });
+
+ it.should("emit when facts are retracted", function(next){
+ var m = new Message("hello");
+ session.once("retract", function(fact){
+ assert.deepEqual(fact, m);
+ next();
+ });
+ session.assert(m);
+ session.retract(m);
+ });
+
+ it.should("emit when facts are modified", function(next){
+ var m = new Message("hello");
+ session.once("modify", function(fact){
+ assert.deepEqual(fact, m);
+ next();
+ });
+ session.assert(m);
+ session.modify(m);
+ });
+
+ it.should("emit when rules are fired", function(next){
+ var m = new Message("hello");
+ var fire = [["Hello", "hello"], ["Goodbye", "hello goodbye"]], i = 0;
+ session.on("fire", function(name, facts){
+ assert.equal(name, fire[i][0]);
+ assert.equal(facts.m.message, fire[i++][1]);
+ });
+ session.assert(m);
+ session.match(function(err){
+ assert.equal(i, 2);
+ next();
+ });
+
+ });
+
+ });
+
it.describe("fibonocci", function (it) {
var Fibonacci = comb.define(null, {
View
@@ -0,0 +1,25 @@
+define Message {
+ message : "",
+ constructor : function (message) {
+ this.message = message;
+ }
+}
+
+rule Hello {
+ when {
+ m : Message m.message =~ /^hello(\\s*world)?$/
+ }
+ then {
+ modify(m, function(){
+ this.message += " goodbye";
+ })
+ }
+}
+
+rule Goodbye {
+ when {
+ m : Message m.message =~ /.*goodbye$/
+ }
+ then {
+ }
+}

0 comments on commit 838e464

Please sign in to comment.