Skip to content

Commit

Permalink
fixed issue noolsjs#13
Browse files Browse the repository at this point in the history
* Fixed constraint matcher to look up identifiers in property chains
  • Loading branch information
doug-martin committed Jan 9, 2013
1 parent 18435ee commit 8780e1b
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 170 deletions.
122 changes: 69 additions & 53 deletions lib/constraintMatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"use strict";

var comb = require("comb"),
isArray = comb.isArray,
dt = comb.date, array = comb.array,
isUndefinedOrNull = comb.isUndefinedOrNull,
removeDups = array.removeDuplicates,
Expand All @@ -10,11 +11,11 @@
vm = require("vm");

var definedFuncs = {
now:function () {
now: function () {
return new Date();
},

Date:function (y, m, d, h, min, s, ms) {
Date: function (y, m, d, h, min, s, ms) {
var date = new Date();
if (comb.isNumber(y)) {
date.setYear(y);
Expand All @@ -40,35 +41,35 @@
return date;
},

lengthOf:function (arr, length) {
lengthOf: function (arr, length) {
return arr.length === length;
},

isTrue:function (val) {
isTrue: function (val) {
return val === true;
},

isFalse:function (val) {
isFalse: function (val) {
return val === false;
},

isRegExp:function (val) {
isRegExp: function (val) {
return comb.isRexExp(val);
},

isNull:function (actual) {
isNull: function (actual) {
return actual === null;
},

isNotNull:function (actual) {
isNotNull: function (actual) {
return actual !== null;
},

dateCmp:function (dt1, dt2) {
dateCmp: function (dt1, dt2) {
return dt.compare(dt1, dt2);
},

isEmpty:function (val) {
isEmpty: function (val) {
return comb.isEmpty(val);
}
};
Expand All @@ -81,15 +82,15 @@

["isArray", "isNumber", "isHash", "isObject", "isDate", "isBoolean", "isString",
"isUndefined", "isDefined", "isUndefinedOrNull", "isPromiseLike", "isFunction", "deepEqual"].forEach(function (k) {
definedFuncs[k] = function (val) {
return comb[k].apply(comb, arguments);
};
});
definedFuncs[k] = function (val) {
return comb[k].apply(comb, arguments);
};
});


var lang = {

equal:function (c1, c2) {
equal: function (c1, c2) {
var ret = false;
if (c1 === c2) {
ret = true;
Expand All @@ -107,9 +108,10 @@
return ret;
},

getIdentifiers:function (rule) {
getIdentifiers: function (rule) {
var ret = [];
var rule2 = rule[2];

if (rule2 === "identifier") {
//its an identifier so stop
return [rule[0]];
Expand All @@ -123,20 +125,34 @@
rule2 !== "unminus") {
//its an expression so keep going
if (rule2 === "prop") {
return ret.concat(this.getIdentifiers(rule[0]));
}
if (rule[0]) {
ret = ret.concat(this.getIdentifiers(rule[0]));
}
if (rule[1]) {
ret = ret.concat(this.getIdentifiers(rule[1]));
if (rule[1]) {
var propChain = rule[1];
//go through the member variables and collect any identifiers that may be in functions
while (isArray(propChain)) {
if (propChain[2] === "function") {
ret = ret.concat(this.getIdentifiers(propChain[1]));
break;
} else {
propChain = propChain[1];
}
}
}

} else {
if (rule[0]) {
ret = ret.concat(this.getIdentifiers(rule[0]));
}
if (rule[1]) {
ret = ret.concat(this.getIdentifiers(rule[1]));
}
}
}
//remove dups and return
return removeDups(ret);
},

toConstraints:function (rule, reference) {
toConstraints: function (rule, reference) {
var ret = [];
var rule2 = rule[2];
if (rule2 === "and") {
Expand Down Expand Up @@ -165,68 +181,68 @@
},


parse:function (rule) {
parse: function (rule) {
return this[rule[2]](rule[0], rule[1]);
},

and:function (lhs, rhs) {
and: function (lhs, rhs) {
return [this.parse(lhs), "&&", this.parse(rhs)].join(" ");
},

or:function (lhs, rhs) {
or: function (lhs, rhs) {
return [this.parse(lhs), "||", this.parse(rhs)].join(" ");
},

prop:function (name, prop) {
prop: function (name, prop) {
return [this.parse(name), this.parse(prop)].join(".");
},

unminus:function (lhs, rhs) {
unminus: function (lhs, rhs) {
return -1 * this.parse(lhs);
},

plus:function (lhs, rhs) {
plus: function (lhs, rhs) {
return [this.parse(lhs), "+", this.parse(rhs)].join(" ");
},
minus:function (lhs, rhs) {
minus: function (lhs, rhs) {
return [this.parse(lhs), "-", this.parse(rhs)].join(" ");
},

mult:function (lhs, rhs) {
mult: function (lhs, rhs) {
return [this.parse(lhs), "*", this.parse(rhs)].join(" ");
},

div:function (lhs, rhs) {
div: function (lhs, rhs) {
return [this.parse(lhs), "/", this.parse(rhs)].join(" ");
},

lt:function (lhs, rhs) {
lt: function (lhs, rhs) {
return [this.parse(lhs), "<", this.parse(rhs)].join(" ");
},
gt:function (lhs, rhs) {
gt: function (lhs, rhs) {
return [this.parse(lhs), ">", this.parse(rhs)].join(" ");
},
lte:function (lhs, rhs) {
lte: function (lhs, rhs) {
return [this.parse(lhs), "<=", this.parse(rhs)].join(" ");
},
gte:function (lhs, rhs) {
gte: function (lhs, rhs) {
return [this.parse(lhs), ">=", this.parse(rhs)].join(" ");
},
like:function (lhs, rhs) {
like: function (lhs, rhs) {
return [this.parse(rhs), ".test(", this.parse(lhs), ")"].join("");
},
eq:function (lhs, rhs) {
eq: function (lhs, rhs) {
return [this.parse(lhs), "===", this.parse(rhs)].join(" ");
},
neq:function (lhs, rhs) {
neq: function (lhs, rhs) {
return [this.parse(lhs), "!==", this.parse(rhs)].join(" ");
},

"in":function (lhs, rhs) {
"in": function (lhs, rhs) {
return ["[", this.parse(rhs), "].indexOf(", this.parse(lhs), ") != -1"].join("");
},

"arguments":function (lhs, rhs) {
"arguments": function (lhs, rhs) {
var ret = [];
if (lhs) {
ret.push(this.parse(lhs));
Expand All @@ -237,7 +253,7 @@
return ret.join(",");
},

"array":function (lhs, rhs) {
"array": function (lhs, rhs) {
var args = [];
if (lhs) {
args = this.parse(lhs);
Expand All @@ -250,44 +266,44 @@
return ["[", args.join(","), "]"].join("");
},

"function":function (lhs, rhs) {
"function": function (lhs, rhs) {
var args = this.parse(rhs), f;
return [lhs, "(", args, ")"].join("");
},

string:function (lhs) {
string: function (lhs) {
return "'" + lhs + "'";
},

number:function (lhs) {
number: function (lhs) {
return lhs;
},

"boolean":function (lhs) {
"boolean": function (lhs) {
return lhs;
},

regexp:function (lhs) {
regexp: function (lhs) {
return lhs;
},

identifier:function (lhs, rhs) {
identifier: function (lhs, rhs) {
return lhs;
},

"null":function (lhs) {
"null": function (lhs) {
return "null";
}
};

var toJs = exports.toJs = function (rule) {
var js = lang.parse(rule);
var js = lang.parse(rule);
var vars = lang.getIdentifiers(rule);
return ["(function(hash){", vars.map(function(v){
return ["(function(hash){", vars.map(function (v) {
var ret = ["var ", v, " = "];
if(definedFuncs.hasOwnProperty(v)){
if (definedFuncs.hasOwnProperty(v)) {
ret.push("definedFuncs['", v, "']");
}else{
} else {
ret.push("hash['", v, "']");
}
ret.push(";");
Expand Down
Loading

0 comments on commit 8780e1b

Please sign in to comment.