def test_resolve_dotsyntax(self): p = Predicate("name is 'Jack' and friend is 'Jill'") doc = { "sub": { "inner": { "val" : 42 } } } assert p.resolve_identifier(doc, "sub.inner.val") == 42
def test_samples(): p = os.path.dirname(os.path.abspath(__file__)) fh = open(os.path.join(p, "preds.txt")) for line, pred in enumerate(fh): pred = pred.strip() obj = Predicate(pred) if not obj.is_valid(): print "Invalid Predicate!" print "Line: ", line print "Predicate: ", pred info = obj.errors() print "Errors: ", "\n".join(info["errors"]) for k, v in info["regex"].iteritems(): print "\t%s : %s" % (k, repr(v)) assert False res, info = obj.analyze(DOC) if not pred.endswith("true") and not pred.endswith("false"): print "Line: ", line print "Unknown result!" print "Predicate: ", pred assert False if (pred.endswith("true") and not res) or (pred.endswith("false") and res): print "Line: ", line print "Predicate: ", pred print "Failures: ", "\n".join(info["failed"]) print "Literals: " for k, v in info["literals"].iteritems(): print "\t%s : %s" % (k, repr(v)) assert False
def test_resolve_custom(self): import random p = Predicate("name is 'Jack' and friend is 'Jill'") p.set_resolver("random", random.random) r1 = p.resolve_identifier({}, "random") r2 = p.resolve_identifier({}, "random") assert r1 != r2
def test_invalid_ast(self): p = Predicate("server matches '(unbal'") assert not p.is_valid() errs = p.errors() assert 'Compilation failed for' in errs["errors"][0] assert 'unbalanced parenthesis' == errs["regex"]["(unbal"] or\ errs["regex"]["(unbal"].startswith("missing ), unterminated subpattern")
def test_jack_and_jill(self): p = Predicate("name is 'Jack'\r\nand friend is 'Jill'") assert p.is_valid() assert p.evaluate({"name": "Jack", "friend": "Jill"}) res, ctx = p.analyze({"name": "Jack", "friend": "Jill"}) assert res assert p.description() == """AND operator at line: 2, col 1
def test_samples(): p = os.path.dirname(os.path.abspath(__file__)) fh = open(os.path.join(p, "preds.txt")) for line, pred in enumerate(fh): pred = pred.strip() obj = Predicate(pred) if not obj.is_valid(): print "Invalid Predicate!" print "Line: ", line print "Predicate: ", pred info = obj.errors() print "Errors: ", "\n".join(info["errors"]) for k, v in info["regex"].iteritems(): print "\t%s : %s" % (k, repr(v)) assert False res, ctx = obj.analyze(DOC) if not pred.endswith("true") and not pred.endswith("false"): print "Line: ", line print "Unknown result!" print "Predicate: ", pred assert False if (pred.endswith("true") and not res) or (pred.endswith("false") and res): print "Line: ", line print "Predicate: ", pred print "Failures: ", "\n".join(ctx.failed) print "Literals: " for k, v in ctx.literals.iteritems(): print "\t%s : %s" % (k, repr(v)) assert False
def test_error(self): p = Predicate("foo is\nbar !! fun") assert not p.is_valid() assert p.errors()['errors'] == [ 'Failed to parse characters !! at line 2, col 5', 'Syntax error with fun at line 2, col 8', ]
def main(): import sys if len(sys.argv) == 2: p = Predicate(sys.argv[1]) if not p.is_valid(): for error in p.errors()['errors']: print(error) return else: p = None rows = [] for id, size, date, sender, msg, dest in mailq(): colsObject = { "cols": [{ "value": id }, { "value": size }, { "value": date }, { "value": sender }, { "value": dest }] } rows.append(colsObject) #doc = list(id, size, date, sender, msg, dest) if p == None or p.evaluate(doc): rowsObject = {"rows": rows} hrowsColsObject = { "cols": [{ "value": "ID" }, { "value": "Size" }, { "value": "Date" }, { "value": "Sender" }, { "value": "Recipient" }] } hrowsColsArray = [] hrowsColsArray.append(hrowsColsObject) hrowsObject = {"hrows": hrowsColsArray} returnString = json.dumps(hrowsObject)[1:-1] + ", " + json.dumps( rowsObject)[1:-1] print(returnString)
class TriggerCondition(object): """Represent a trigger condition""" def __init__(self, predicate): from pypred import Predicate self.predicate = Predicate(predicate) if not self.predicate.is_valid(): raise ValueError('Predicate is invalid: ' + str(predicate)) def satisfied_by(self, execution_context): """test the predicate against the execution context""" return self.predicate.evaluate(execution_context)
def test_finalize(self): p1 = Predicate("name is 'Jack'") p2 = Predicate("name is 'Jill'") s = OptimizedPredicateSet([p1, p2]) s.finalize() match = s.evaluate({'name': 'Jill'}) assert match == [p2] p3 = Predicate("name is 'Joe'") with pytest.raises(Exception): s.add(p3)
def test_invalidate(self): "AST is invalidated when set changes" p1 = Predicate("name is 'Jack'") p2 = Predicate("name is 'Jill'") s = OptimizedPredicateSet([p1, p2]) match = s.evaluate({'name': 'Jill'}) assert match == [p2] p3 = Predicate("name is 'Joe'") s.add(p3) assert s.ast == None match = s.evaluate({'name': 'Joe'}) assert match == [p3]
def gen_predicates(num): res = [] for x in range(num): r = random.randint(0, 5) if r == 0: p_str = "name is '%s' and not test" % random.choice(SELECT_WORDS) elif r == 1: gender = "Male" if random.random() > 0.5 else "Female" age = random.randint(1, 100) p_str = "gender is '%s' and age > %d" % (gender, age) elif r == 2: city_letter = chr(97 + random.randint(0, 25)) city_reg = "^%s.*" % city_letter age = random.randint(1, 100) p_str = "age > %d and city matches '%s'" % (age, city_reg) elif r == 3: interest = random.choice(SELECT_WORDS) p_str = "interests contains '%s' and test" % interest elif r == 4: gender = "Male" if random.random() else "Female" p_str = "name is '%s' or gender is '%s'" % ( random.choice(SELECT_WORDS), gender) elif r == 5: gender = "Male" if random.random() else "Female" age = random.randint(1, 100) p_str = "(age > %d and gender is '%s')" % (age, gender) gender = "Male" if random.random() else "Female" age = random.randint(1, 100) p_str += " or (age < %d and gender is '%s')" % (age, gender) p = Predicate(p_str) res.append(p) return res
def test_samples(): p = os.path.dirname(os.path.abspath(__file__)) fh = open(os.path.join(p, "preds.txt")) s1 = PredicateSet() s2 = OptimizedPredicateSet() match = [] for line, pred in enumerate(fh): pred = pred.strip() obj = Predicate(pred) # Add to the set s1.add(obj) s2.add(obj) # Add to the list of matches if pred.endswith("true"): match.append(pred) # Run the sets s1_match = s1.evaluate(DOC) s2_match = s2.evaluate(DOC) # Ensure both match match.sort() s1_match = [p.predicate for p in s1_match] s1_match.sort() s2_match = [p.predicate for p in s2_match] s2_match.sort() assert s1_match == match assert s2_match == match
def test_jack_and_jill(self): p = Predicate("name is 'Jack' and friend is 'Jill'") assert p.is_valid() assert p.evaluate({"name": "Jack", "friend": "Jill"}) res, ctx = p.analyze({"name": "Jack", "friend": "Jill"}) assert res assert ( p.description() == """AND operator at line: 1, col 15 IS comparison at line: 1, col 5 Literal name at line: 1, col 0 Literal 'Jack' at line: 1, col 8 IS comparison at line: 1, col 26 Literal friend at line: 1, col 19 Literal 'Jill' at line: 1, col 29 """ )
def check_condition(self, tracker, condition): if condition is None: return True if isinstance(condition, str): slots = dict() for slotName, slotValue in tracker.slots.items(): slots[slotName] = slotValue.value predicate = Predicate(condition) if predicate.is_valid() is not True: return False result = predicate.evaluate(slots) return result props = condition.get("properties", {}) children = condition.get("children1", {}).values() if condition.get("type") == "rule": return self.check_atomic_condition(tracker, **props) conjunction_operator = any if props.get("conjunction") == "OR" else all polarity = (lambda p: not p) if props.get("not") else (lambda p: p) return polarity( conjunction_operator( self.check_condition(tracker, child) for child in children))
def test_invalid_end(self): p = Predicate("name is 'Jack' and ") assert not p.is_valid() assert 'Unexpected end of predicate!' in p.errors()["errors"]
def test_resolve_dotsyntax(self): p = Predicate("name is 'Jack' and friend is 'Jill'") doc = {"sub": {"inner": {"val": 42}}} assert p.resolve_identifier(doc, "sub.inner.val") == 42
def test_resolve_quote(self): p = Predicate("name is 'Jack' and friend is 'Jill'") assert p.resolve_identifier({}, "'name'") == "name" assert p.resolve_identifier({}, "\"name\"") == "name"
def test_resolve_missing(self): p = Predicate("name is 'Jack' and friend is 'Jill'") assert p.resolve_identifier({}, "name") == ast.Undefined()
def test_resolve_present(self): p = Predicate("name is 'Jack' and friend is 'Jill'") assert p.resolve_identifier({"name": "abc"}, "name") == "abc"
def test_invalid_parse(self): p = Predicate("true true") assert not p.is_valid() assert "Syntax error with true" in p.errors()["errors"][0]
def test_invalid_ast(self): p = Predicate("server matches '(unbal'") assert not p.is_valid() errs = p.errors() assert "Compilation failed for" in errs["errors"][0] assert "unbalanced parenthesis" == errs["regex"]["(unbal"]
def test_resolve_custom_fixed(self): p = Predicate("name is 'Jack' and friend is 'Jill'") p.set_resolver("answer", 42) r1 = p.resolve_identifier({}, "answer") assert r1 == 42
def test_dup(self): p1 = Predicate("name is 'Jill'") s = OptimizedPredicateSet([p1, p1]) match = s.evaluate({'name': 'Jill'}) assert match == [p1]
def test_invalid_ast(self): p = Predicate("server matches '(unbal'") assert not p.is_valid() errs = p.errors() assert 'Compilation failed for' in errs["errors"][0] assert 'unbalanced parenthesis' == errs["regex"]["(unbal"]
def __init__(self, predicate): from pypred import Predicate self.predicate = Predicate(predicate) if not self.predicate.is_valid(): raise ValueError('Predicate is invalid: ' + str(predicate))
def test_invalid_end(self): p = Predicate("name is 'Jack' and ") assert not p.is_valid() assert "Unexpected end of predicate!" in p.errors()["errors"]
def test_invalid_token(self): p = Predicate("name is !! and true") assert not p.is_valid() assert 'Failed to parse characters !!' in p.errors()["errors"][0]
def test_invalid_parse(self): p = Predicate("true true") assert not p.is_valid() assert 'Syntax error with true' in p.errors()["errors"][0]
def test_invalid_token(self): p = Predicate("name is !! and true") assert not p.is_valid() assert "Failed to parse characters !!" in p.errors()["errors"][0]
def test_two(self): p1 = Predicate("name is 'Jack'") p2 = Predicate("name is 'Jill'") s = PredicateSet([p1, p2]) match = s.evaluate({'name': 'Jill'}) assert match == [p2]
def test_resolve_quote(self): p = Predicate("name is 'Jack' and friend is 'Jill'") assert p.resolve_identifier({}, "'name'") == "name" assert p.resolve_identifier({}, '"name"') == "name"