def test_ser_simple_math(self): expected = "1 in (4,3,2,1,0,)" in_ = to_criteria(expected) self.assertIsInstance(in_, In) self.assertEqual(in_.key, 1) self.assertEqual(in_.right, ( 4, 3, 2, 1, 0, )) (ans, err) = in_(Ctx({})) self.assertTrue(ans) self.assertIsNone(err) text = str(in_) self.assertEqual(expected, text) expected = "1 in (4,3,2,0,-1,)" in_ = to_criteria(expected) self.assertIsInstance(in_, In) self.assertEqual(in_.key, 1) self.assertEqual(in_.right, ( 4, 3, 2, 0, -1, )) (ans, err) = in_(Ctx({})) self.assertFalse(ans) self.assertIsNone(err) text = str(in_) self.assertEqual(expected, text)
def test_simple_bool_eq(self): ctx = Ctx({"active": True}) expected = "active == True" c = to_criteria(expected) self.assertIsInstance(c, Eq) self.assertEqual(c.key, "active") self.assertEqual(c.right, True) (ans, err) = c(ctx) self.assertTrue(ans) self.assertIsNone(err) text = str(c) self.assertEqual(expected, text) expected = "active" c = to_criteria(expected) self.assertIsInstance(c, Bool) self.assertEqual(c.key, "active") (ans, err) = c(ctx) self.assertTrue(ans) self.assertIsNone(err) text = str(c) self.assertEqual(expected, text)
def test_ser_not_in(self): with acura_small as acura: ctx = Ctx(acura) for expected in ( "make not in ('Acura',)", "make not in ('Ford','Chrysler','Eagle','Honda','Acura',)" ): not_in_ = to_criteria(expected) text = str(not_in_) self.assertEqual(expected, text) (ans, err) = not_in_(ctx) self.assertFalse(ans) self.assertIsNone(err) for expected in ( "make not in ('Ford',)", "make not in ('Ford','Chrysler','Eagle','Honda','Mazda',)" ): in_ = to_criteria(expected) text = str(in_) self.assertEqual(expected, text) (ans, err) = in_(ctx) self.assertTrue(ans) self.assertIsNone(err)
def test_ser_not_bool(self): expected = "not (active)" not_ = to_criteria(expected) text = str(not_) self.assertEqual(expected, text) text2 = "not active" not2_ = to_criteria(text2) text3 = str(not2_) self.assertNotEqual(text2, text3) self.assertEqual(text3, expected) expected = "not (True)" not_ = to_criteria(expected) text = str(not_) self.assertEqual(expected, text) text2 = "not True" not2_ = to_criteria(text2) text3 = str(not2_) self.assertNotEqual(text2, text3) self.assertEqual(text3, expected) expected = "not (1)" text2 = "not 1" not2_ = to_criteria(text2) text3 = str(not2_) self.assertNotEqual(text2, text3) self.assertEqual(text3, expected) (ans, err) = not2_(Ctx({})) self.assertFalse(ans) self.assertIsNone(err)
def test_and_and_nesting(self): with acura_small as acura: ctx = Ctx(acura) expected = "(source == 'USA' or ((make == 'Mazda' or type == 'Midsize') or maxprice == 18.8))" or_ = Or( Eq("source", "USA"), Or(Or(Eq("make", "Mazda"), Eq("type", "Midsize")), Eq("maxprice", 18.8))) (ans, err) = or_(ctx) text = str(or_) self.assertEqual(expected, text) self.assertTrue(ans) self.assertIsNone(err) or2_ = to_criteria(expected) self.assertIsInstance(or2_, Or) self.assertEqual(expected, str(or2_)) expected = "source == 'USA' or make == 'Mazda' or type == 'Midsize' or maxprice == 18.8" any_ = Any(Eq("source", "USA"), Eq("make", "Mazda"), Eq("type", "Midsize"), Eq("maxprice", 18.8)) text = str(any_) self.assertEqual(expected, text) (ans_, err_) = any_(ctx) self.assertTrue(ans) self.assertEqual(ans, ans_) self.assertEqual(err, err_) self.assertNotEqual(str(or_), str(any_)) any2_ = to_criteria(expected) self.assertIsInstance(any2_, Any) self.assertEqual(expected, str(any2_))
def test_bool_op_all(self): ctx = Ctx({"active": True, "score": 92, "valid": False}) original = "active and score >= 90 and valid != True" expected = original all_ = to_criteria(original) self.assertIsInstance(all_, All) active, score, valid = all_.many self.assertIsInstance(active, Bool) self.assertIsInstance(score, GtE) self.assertIsInstance(valid, NotEq) (ans, err) = all_(ctx) self.assertTrue(ans) self.assertIsNone(err) text = str(all_) self.assertEqual(expected, text) original = "active and (score >= 90 and valid != True)" expected = "(active and (score >= 90 and valid != True))" and_ = to_criteria(original) self.assertIsInstance(and_, And) active = and_.left and_2nd = and_.right self.assertIsInstance(and_2nd, And) score, valid = and_2nd.left, and_2nd.right self.assertIsInstance(active, Bool) self.assertIsInstance(score, GtE) self.assertIsInstance(valid, NotEq) (ans, err) = and_(ctx) self.assertTrue(ans) self.assertIsNone(err) text = str(and_) self.assertEqual(expected, text)
def test_between(self): expected = "50 <= price < 100" c = to_criteria(expected) self.assertIsInstance(c, Between) self.assertEqual(c.lower, 50) self.assertEqual(c.lower_op, operator.le) self.assertEqual(c.key, "price") self.assertEqual(c.upper_op, operator.lt) self.assertEqual(c.upper, 100) (ans, err) = c(Ctx({"price": 75})) self.assertTrue(ans) self.assertIsNone(err) text = str(c) self.assertEqual(expected, text) expected = "44.1 < score <= 66.2" c = to_criteria(expected) self.assertIsInstance(c, Between) self.assertEqual(c.lower, 44.1) self.assertEqual(c.lower_op, operator.lt) self.assertEqual(c.key, "score") self.assertEqual(c.upper_op, operator.le) self.assertEqual(c.upper, 66.2) (ans, err) = c(Ctx({"score": 55.6})) self.assertTrue(ans) self.assertIsNone(err) text = str(c) self.assertEqual(expected, text)
def test_ser_in(self): with acura_small as acura: expected = "make in ('Acura',)" in_ = to_criteria(expected) text = str(in_) self.assertEqual(expected, text) expected = "make in ('Ford','Chrysler','Eagle','Honda','Acura','Mazda',)" in_ = to_criteria(expected) text = str(in_) self.assertEqual(expected, text) (ans, err) = in_(Ctx(acura)) self.assertTrue(ans) self.assertIsNone(err)
def test_bool_op_any(self): ctx = Ctx({"active": True, "score": 92, "valid": False}) expected = "active or score >= 90 or valid != True" any_ = to_criteria(expected) self.assertIsInstance(any_, Any) sunny, score, funny = any_.many self.assertIsInstance(sunny, Bool) self.assertIsInstance(score, GtE) self.assertIsInstance(funny, NotEq) (ans, err) = any_(ctx) self.assertTrue(ans) self.assertIsNone(err) text = str(any_) self.assertEqual(expected, text) original = "active or (score >= 90 or valid != True)" expected = "(active or (score >= 90 or valid != True))" or_ = to_criteria(original) self.assertIsInstance(or_, Or) active = or_.left or_2nd = or_.right self.assertIsInstance(or_2nd, Or) score, valid = or_2nd.left, or_2nd.right self.assertIsInstance(sunny, Bool) self.assertIsInstance(score, GtE) self.assertIsInstance(valid, NotEq) (ans, err) = or_(ctx) self.assertTrue(ans) self.assertIsNone(err) text = str(or_) self.assertEqual(expected, text) original = "(active or score >= 90) or valid != True" expected = "((active or score >= 90) or valid != True)" or_ = to_criteria(original) self.assertIsInstance(or_, Or) or_2nd = or_.left self.assertIsInstance(or_2nd, Or) active, score = or_2nd.left, or_2nd.right valid = or_.right self.assertIsInstance(active, Bool) self.assertIsInstance(score, GtE) self.assertIsInstance(valid, NotEq) (ans, err) = or_(ctx) self.assertTrue(ans) self.assertIsNone(err) text = str(or_) self.assertEqual(expected, text)
def test_ser_not_eq(self): expected = "not (make == 'Acura')" not_ = Not(Eq("make", "Acura")) text = str(not_) self.assertEqual(text, expected) not2_ = to_criteria(text) self.assertIsInstance(not2_, Not) text2 = str(not2_) self.assertEqual(text, text2) text3 = "not make == 'Acura'" not3_ = to_criteria(text3) self.assertIsInstance(not3_, Not) text4 = str(not3_) self.assertNotEquals(text3, text4) self.assertEqual(text4, expected)
def test_not(self): ctx = Ctx({"active": False, "score": 50}) for text in ("not active", "not (active)"): not_active = to_criteria(text) self.assertIsInstance(not_active, Not) self.assertIsInstance(not_active.one, Bool) (ans, err) = not_active(ctx) self.assertTrue(ans) self.assertIsNone(err) ser = str(not_active) self.assertEqual("not (active)", ser) for text in ( "not 44.1 < score <= 66.2", "not (44.1 < score <= 66.2)", ): c = to_criteria(text) self.assertIsInstance(c, Not) btw = c.one self.assertIsInstance(btw, Between) self.assertEqual(btw.lower, 44.1) self.assertEqual(btw.lower_op, operator.lt) self.assertEqual(btw.key, "score") self.assertEqual(btw.upper_op, operator.le) self.assertEqual(btw.upper, 66.2) (ans, err) = c(ctx) self.assertFalse(ans) self.assertIsNone(err) ser = str(c) self.assertEqual("not (44.1 < score <= 66.2)", ser) for text in ( "not active == True", "not (active == True)", ): c = to_criteria(text) self.assertIsInstance(c, Not) eq = c.one self.assertEqual(eq.key, "active") self.assertEqual(eq.right, True) (ans, err) = eq(ctx) self.assertFalse(ans) self.assertIsNone(err) ser = str(c) self.assertEqual("not (active == True)", ser)
def test_no_key(self): ctx = Ctx({}) expected = "1 <= 2 < 3" btw = to_criteria(expected) text = str(btw) self.assertEqual(expected, text) (ans, err) = btw(ctx) self.assertTrue(ans) self.assertIsNone(err) expected = "3 <= 3 < 3" btw = to_criteria(expected) text = str(btw) self.assertEqual(expected, text) (ans, err) = btw(ctx) self.assertFalse(ans) self.assertIsNone(err)
def test_ser_gt(self): expected = "maxprice > 0.99" gt = Gt("maxprice", 0.99) text = str(gt) self.assertEqual(expected, text) gt2 = to_criteria(text) self.assertEqual(gt.key, gt2.key) self.assertEqual(gt.right, gt2.right) self.assertEqual(gt.op, gt2.op)
def test_ser(self): expected = "234 < score <= 456" btw = to_criteria(expected) self.assertIsInstance(btw, Between) self.assertEqual(btw.lower, 234) self.assertEqual(btw.lower_op, operator.lt) self.assertEqual(btw.key, "score") self.assertEqual(btw.upper_op, operator.le) self.assertEqual(btw.upper, 456) text = str(btw) self.assertEqual(expected, text)
def test_none(self): eq = Eq("make", None) expected = "make == None" self.assertEqual(expected, str(eq)) eq2 = to_criteria(expected) self.assertEqual(eq2.key, "make") self.assertIsNone(eq2.right) car = {"make": None} (ans, err) = eq(car)
def test_in(self): ctx = Ctx({"score": 92}) expected = "score in (90,91,92,)" in_ = to_criteria(expected) self.assertIsInstance(in_, In) self.assertEqual(in_.key, "score") self.assertEqual(len(in_.right), 3) (ans, err) = in_(ctx) self.assertTrue(ans) self.assertIsNone(err) text = str(in_) self.assertEqual(expected, text)
def test_true_eq_true(self): ctx = Ctx({}) text = "True == 'True'" c = to_criteria(text) self.assertIsInstance(c, Eq) self.assertEqual(c.key, True) self.assertEqual(c.right, "True") (ans, err) = c(ctx) self.assertFalse(ans) self.assertIsNone(err) text = "'True' == 'True'" c = to_criteria(text) self.assertIsInstance(c, Eq) self.assertEqual(c.key, "True") self.assertEqual(c.right, "True") (ans, err) = c(ctx) self.assertFalse(ans) self.assertIsNone(err) text = "True == True" c = to_criteria(text) self.assertIsInstance(c, Eq) self.assertEqual(c.key, True) self.assertEqual(c.right, True) (ans, err) = c(ctx) self.assertTrue(ans) self.assertIsNone(err) text = "'True' == True" c = to_criteria(text) self.assertIsInstance(c, Eq) self.assertEqual(c.key, "True") self.assertEqual(c.right, True) (ans, err) = c(ctx) self.assertTrue(ans) self.assertIsNone(err)
def test_universal(self): notIn = NotIn("make", universal) expected = "make not in ('*',)" self.assertEqual(expected, str(notIn)) notIn = to_criteria(expected) self.assertIn(universal, notIn.right) self.assertEqual(expected, str(notIn)) for value in ("xyz", 1, 0, 10.3, False, True, object(), "*"): car = {"make": value} (ans, err) = notIn(car) self.assertFalse(ans) self.assertIsNone(err)
def test_ser(self): with acura_small as acura: expected = "make != 'Acura'" not_eq = to_criteria(expected) text = str(not_eq) self.assertEqual(expected, text) self.assertIsInstance(not_eq, NotEq) self.assertEqual(not_eq.key, 'make') self.assertEqual(not_eq.right, 'Acura') self.assertEqual(not_eq.op, operator.ne) (ans, err) = not_eq(Ctx(acura)) self.assertFalse(ans) self.assertIsNone(err)
def test_universal(self): eq = Eq("make", universal) expected = "make == '*'" self.assertEqual(expected, str(eq)) eq = to_criteria(expected) self.assertEqual(eq.right, Const.universal) self.assertEqual(expected, str(eq)) for value in ("xyz", 1, 0, 10.3, False, True, object(), "*"): car = {"make": value} (ans, err) = eq(car) self.assertTrue(ans) self.assertIsNone(err)
def test_universal(self): in_ = In("make", universal) expected = "make in ('*',)" self.assertEqual(expected, str(in_)) in_ = to_criteria(expected) self.assertIn(universal, in_.right) self.assertEqual(expected, str(in_)) for value in ("xyz", 1, 0, 10.3, False, True, object(), "*"): car = {"make": value} (ans, err) = in_(car) self.assertTrue(ans) self.assertIsNone(err)
def test_ser_simple_str(self): expected = "True in (False,'False',0,1,)" in_ = to_criteria(expected) self.assertIsInstance(in_, In) self.assertEqual(in_.key, True) self.assertEqual(in_.right, ( False, 'False', 0, 1, )) (ans, err) = in_(Ctx({})) self.assertTrue(ans) self.assertIsNone(err) text = str(in_) self.assertEqual(expected, text)
def test_criteria_call(self): car_search_criteria = to_criteria("cpu == 'Intel' and make == 'Acura' and type == 'Midsize' and drivetrain == 'Front'") (ans, err) = car_search_criteria(acura) self.assertEqual(ans, Const.ERROR) self.assertIsInstance(err, KeyError) (ans, err) = car_search_criteria(Ctx(acura)) self.assertEqual(ans, Const.ERROR) self.assertIsInstance(err, KeyError) (ans, err) = car_search_criteria(acura, True) self.assertTrue(ans) self.assertIsInstance(err, KeyError) (ans, err) = car_search_criteria(Ctx(acura, True)) self.assertTrue(ans) self.assertIsInstance(err, KeyError)
def test_bool_op_and(self): ctx = Ctx({"active": 'True', "score": 92}) text = "active == True and score > 90" and_ = to_criteria(text) self.assertIsInstance(and_, And) eq_, gt_ = and_.left, and_.right self.assertIsInstance(eq_, Eq) self.assertIsInstance(gt_, Gt) (ans, err) = eq_(ctx) self.assertFalse(ans) # eq( True, 'True') is False self.assertIsNone(err) (ans, err) = gt_(ctx) self.assertTrue(ans) self.assertIsNone(err) (ans, err) = and_(ctx) self.assertFalse(ans) # False and True is False self.assertIsNone(err)
def test_ser_all(self): ctx = Ctx(acura) expected = "make == 'Acura' and 15 <= maxprice < 20.1 and source != 'USA' and type == 'Small'" all_ = to_criteria(expected) all2_ = Criteria().Eq("make", "Acura").Between(15, "maxprice", 20.1).NotEq( "source", "USA").Eq("type", "Small").All().Done() self.assertEqual(expected, str(all_)) self.assertEqual(expected, str(all2_)) (ans, err) = all_(ctx) (ans_, err_) = all2_(ctx) self.assertEqual(ans, ans_) self.assertEqual(err, err_)
def test_all_and_any_or(self): ctx = Ctx({"active": 1, "score": 92, "valid": 0}) original = "active and score >= 90 or valid != True" expected = "((active and score >= 90) or valid != True)" or_ = to_criteria(original) self.assertIsInstance(or_, Or) and_ = or_.left valid = or_.right self.assertIsInstance(and_, And) active, score = and_.left, and_.right self.assertIsInstance(active, Bool) self.assertIsInstance(score, GtE) self.assertIsInstance(valid, NotEq) (ans, err) = or_(ctx) self.assertTrue(ans) self.assertIsNone(err) text = str(or_) self.assertEqual(expected, text)
def test_bool_op_or(self): ctx = Ctx({"active": True, "score": 92}) original = "active == True or score > 90" expected = "(active == True or score > 90)" or_ = to_criteria(original) self.assertIsInstance(or_, Or) eq_, gt_ = or_.left, or_.right self.assertIsInstance(eq_, Eq) self.assertIsInstance(gt_, Gt) (ans, err) = eq_(ctx) self.assertTrue(ans) self.assertIsNone(err) (ans, err) = gt_(ctx) self.assertTrue(ans) self.assertIsNone(err) (ans, err) = or_(ctx) self.assertTrue(ans) self.assertIsNone(err) text = str(or_) self.assertEqual(expected, text)
def test_filter_cars(self): """ create criteria either through api or text """ expected = "((17 <= maxprice < 21 and make == 'Chevrolet') and type == 'Compact')" car_search_criteria = Criteria().Between(17, "maxprice", 21).Eq("make", "Chevrolet").And().Eq("type", "Compact").And().Done() car_search_criteria2 = to_criteria(expected) self.assertEqual(str(car_search_criteria), expected) self.assertEqual(str(car_search_criteria2), expected) """ test that one of the cars below matches the criteria """ ctx = Ctx(chevrolet_compact_e) (ans, err) = car_search_criteria(ctx) self.assertTrue(ans) self.assertIsNone(err) ctx = Ctx(chevrolet_compact_c) (ans, err) = car_search_criteria(ctx) self.assertFalse(ans) self.assertIsNone(err) """ to conform to built-in filter function's requirement """ def predicate(car): (ans, _) = car_search_criteria(Ctx(car)) return ans """ there should be only be one match """ potential = filter(predicate, CARS) self.assertEqual(len(potential), 1) """ change search criteria a bit """ car_search_criteria = Criteria().Eq("make", "Chevrolet").Eq("type", "Compact").Eq("source", "USA").All().Done() def predicate(car): (ans, _) = car_search_criteria(Ctx(car)) return ans potential = filter(predicate, CARS) self.assertEqual(len(potential), 2)
def test_single_word_bool_criteria_alone(self): ctx = Ctx({"active": True}) tests = list() tests.append(('True', True, bool, True, None)) tests.append(('"True"', 'True', bool, True, None)) tests.append(('1', 1, bool, True, None)) tests.append(('False', False, bool, False, None)) tests.append(('"False"', 'False', bool, False, None)) tests.append(('0', 0, bool, False, None)) tests.append(('active', 'active', bool, True, None)) tests.append(('cpu', 'cpu', type(Const.ERROR), Const.ERROR, KeyError)) for (text_, equal_, type_, ans_, err_) in tests: c = to_criteria(text_) self.assertIsInstance(c, Criteria) self.assertIsInstance(c, Bool) self.assertEqual(c.key, equal_) (ans, err) = c(ctx) self.assertIsInstance(ans, type_) self.assertEqual(ans, ans_) self.assertIsInstance(err, err_) if err_ else self.assertIsNone(err)
def test_and_simple_boolean(self): or_ = Or(cTrue, cTrue) (ans, err) = or_(Ctx({})) self.assertTrue(ans) self.assertIsNone(err) text = str(or_) or2_ = to_criteria(text) text2 = str(or2_) self.assertEqual(text, text2) any_ = Any(cTrue, cTrue) (ans_, err_) = any_(Ctx({})) self.assertEqual(ans, ans_) self.assertEqual(err, err_) text = str(any_) """ since there are only 2 operands, it's considered Or during parsing""" or2_ = to_criteria(text) self.assertIsInstance(or2_, Or) """ therefore during ser, it's different from str of any """ text2 = str(or2_) self.assertNotEqual(text, text2) or_ = Or(cTrue, cFalse) (ans, err) = or_(Ctx({})) self.assertTrue(ans) self.assertIsNone(err) text = str(or_) or2_ = to_criteria(text) text2 = str(or2_) self.assertEqual(text, text2) any_ = Any(cTrue, cFalse) (ans_, err_) = any_(Ctx({})) self.assertEqual(ans, ans_) self.assertEqual(err, err_) text = str(any_) """ since there are only 2 operands, it's considered Or during parsing""" or2_ = to_criteria(text) self.assertIsInstance(or2_, Or) """ therefore during ser, it's different from str of any """ text2 = str(or2_) self.assertNotEqual(text, text2) or_ = Or(cFalse, cTrue) (ans, err) = or_(Ctx({})) self.assertTrue(ans) self.assertIsNone(err) text = str(or_) or2_ = to_criteria(text) text2 = str(or2_) self.assertEqual(text, text2) any_ = Any(cFalse, cTrue) (ans_, err_) = any_(Ctx({})) self.assertEqual(ans, ans_) self.assertEqual(err, err_) text = str(any_) """ since there are only 2 operands, it's considered Or during parsing""" or2_ = to_criteria(text) self.assertIsInstance(or2_, Or) """ therefore during ser, it's different from str of any """ text2 = str(or2_) self.assertNotEqual(text, text2) or_ = Or(cFalse, cFalse) (ans, err) = or_(Ctx({})) self.assertFalse(ans) self.assertIsNone(err) text = str(or_) or2_ = to_criteria(text) text2 = str(or2_) self.assertEqual(text, text2) any_ = Any(cFalse, cFalse) (ans_, err_) = any_(Ctx({})) self.assertEqual(ans, ans_) self.assertEqual(err, err_) text = str(any_) """ since there are only 2 operands, it's considered Or during parsing""" or2_ = to_criteria(text) self.assertIsInstance(or2_, Or) """ therefore during ser, it's different from str of any """ text2 = str(or2_) self.assertNotEqual(text, text2)