Permalink
Browse files

fixed issue #13

* Fixed constraint matcher to look up identifiers in property chains
  • Loading branch information...
1 parent 18435ee commit 8780e1b53c061c54c043fc3aa4cc862478c9b06d @doug-martin doug-martin committed Jan 9, 2013
Showing with 239 additions and 170 deletions.
  1. +69 −53 lib/constraintMatcher.js
  2. +170 −117 test/constraintMatcher.test.js
@@ -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,
@@ -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);
@@ -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);
}
};
@@ -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;
@@ -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]];
@@ -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") {
@@ -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));
@@ -237,7 +253,7 @@
return ret.join(",");
},
- "array":function (lhs, rhs) {
+ "array": function (lhs, rhs) {
var args = [];
if (lhs) {
args = this.parse(lhs);
@@ -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(";");
Oops, something went wrong.

0 comments on commit 8780e1b

Please sign in to comment.