def test_ser_not_eq(self): with acura_midsize as acura: eq = Eq("type", "Midsize") (ans, err) = eq(Ctx(acura)) self.assertTrue(ans) self.assertIsNone(err) text = str(eq) self.assertEqual(text, "type == 'Midsize'") not_eq = NotEq("type", "Midsize") (ans, err) = not_eq(Ctx(acura)) self.assertFalse(ans) self.assertIsNone(err) text = str(not_eq) self.assertEqual(text, "type != 'Midsize'") not_eq = NotEq("maxprice", 19.9) (ans, err) = not_eq(Ctx(acura)) self.assertTrue(ans) self.assertIsNone(err) text = str(not_eq) self.assertEqual(text, "maxprice != 19.9") not_eq = NotEq("pass", True) text = str(not_eq) self.assertEqual(text, "pass != True")
def test_missing_info(self): for ctx, expected in [(Ctx({}, False), Const.ERROR), (Ctx({}, True), Const.UNKNOWN)]: btw_ = Between(10, "price", 20) (ans, err) = btw_(ctx) self.assertEqual(ans, expected) self.assertIsInstance(err, KeyError)
def test_in_simple(self): with acura_small as acura: in_ = In("make", "Acura") (ans, err) = in_(Ctx(acura)) self.assertTrue(ans) self.assertIsNone(err) in_ = In("make", "Ford", "Chrysler", "Eagle", "Honda", "Acura", "Mazda") (ans, err) = in_(Ctx(acura)) self.assertTrue(ans) self.assertIsNone(err) in_ = In( "make", "Ford", ) (ans, err) = in_(Ctx(acura)) self.assertFalse(ans) self.assertIsNone(err) in_ = In("make", "Ford", "Chrysler", "Eagle", "Honda") (ans, err) = in_(Ctx(acura, True)) self.assertFalse(ans) self.assertIsNone(err)
def test_basic_compare(self): values = ['True', True, 'true', 'tRUE', 1] active = Bool("active") for value in values: ctx = Ctx({"active": value}) (obj, err) = active(ctx) self.assertTrue(obj) self.assertIsNone(err) not_active = Not(active) (obj, err) = not_active(ctx) self.assertFalse(obj) self.assertIsNone(err) values = [False, 'False', 'false', 'fALSE', 0] active = Bool("active") for value in values: ctx = Ctx({"active": value}) (obj, err) = active(ctx) self.assertFalse(obj) self.assertIsNone(err) not_active = Not(active) (obj, err) = not_active(ctx) self.assertTrue(obj) self.assertIsNone(err)
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_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_all_unknown_fuzzy_on_off(self): ctx = Ctx(acura, True) all_ = Criteria().Eq("x", "x").Eq("y", "y").Eq("z", "z").Eq("w", "w").All().Done() (ans, err) = all_(ctx) self.assertEqual(ans, Const.UNKNOWN) self.assertIsInstance(err, KeyError) and_ = Criteria().Eq("x", "x").Eq("y", "y").And().Eq("z", "z").And().Eq( "w", "w").And().Done() (ans_, err_) = and_(ctx) self.assertEqual(ans, ans_) self.assertEqual(err.message, err_.message) ctx = Ctx(acura, False) all_ = Criteria().Eq("x", "x").Eq("y", "y").Eq("z", "z").Eq("w", "w").All().Done() (ans, err) = all_(ctx) self.assertEqual(ans, Const.ERROR) self.assertIsInstance(err, KeyError) and_ = Criteria().Eq("x", "x").Eq("y", "y").And().Eq("z", "z").And().Eq( "w", "w").And().Done() (ans_, err_) = and_(ctx) self.assertEqual(ans, ans_) self.assertEqual(err.message, err_.message)
def test_not_simple(self): not_ = Not(cTrue) (ans, err) = not_(Ctx({})) self.assertFalse(ans) self.assertIsNone(err) not_ = Not(cFalse) (ans, err) = not_(Ctx({})) self.assertTrue(ans) self.assertIsNone(err)
def test_not_and(self): and_ = And(cTrue, cFalse) not_ = Not(and_) (ans, err) = not_(Ctx({})) self.assertTrue(ans) self.assertIsNone(err) not__ = Not(not_) (ans, err) = not__(Ctx({})) self.assertFalse(ans) self.assertIsNone(err)
def test_basic_init(self): for ctx in [Ctx({}, False), Ctx({}, True)]: for c in [cTrue, Bool(True), Bool('True'), Bool(1)]: (obj, err) = c(ctx) self.assertTrue(obj) self.assertIsNone(err) for c in [cFalse, Bool(False), Bool('False'), Bool(0)]: (obj, err) = c(ctx) self.assertFalse(obj) self.assertIsNone(err)
def test_eq_missing_attribute(self): with acura_small as acura: eq = Eq("cpu", "Intel") ctx = Ctx(acura, True) (ans, error) = eq(ctx) self.assertTrue(ctx.fuzzy) self.assertEqual(ans, Const.UNKNOWN) self.assertIsInstance(error, KeyError) ctx = Ctx(acura, False) (ans, error) = eq(ctx) self.assertFalse(ctx.fuzzy) self.assertEqual(ans, Const.ERROR) self.assertIsInstance(error, KeyError)
def test_targets(self): with acura_small as acura: for fuzzy in (True, False): ctx = Ctx(acura, fuzzy) self.assertEqual(ctx["make"], "Acura") self.assertEqual(ctx["type"], "Small") self.assertEqual(ctx.fuzzy, fuzzy)
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_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_le_positive(self): with acura_small as acura: le_ = LtE("maxprice", 18.8) (ans, err) = le_(Ctx(acura)) self.assertTrue(ans) self.assertIsNone(err) le_ = LtE("maxprice", 18.81) (ans, err) = le_(Ctx(acura)) self.assertTrue(ans) self.assertIsNone(err) le_ = LtE("maxprice", 18.79) (ans, err) = le_(Ctx(acura)) self.assertFalse(ans) self.assertIsNone(err)
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_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_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_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_get(self): ctx = Ctx(acura_small) make = ctx["make"] self.assertEqual(make, "Acura") with self.assertRaises(KeyError): ctx["cpu"] cpu = ctx.get("cpu", default="Intel") self.assertEqual(cpu, "Intel")
def test_and_left_cmp_error(self): with acura: ctx = Ctx(acura, True) acura.set_compare_error("make", CompareError(Exception("left first"))) acura.set_compare_error("source", CompareError(KeyError("right first"))) make = ctx["make"] source = ctx["source"] (obj, err) = Eq("make", "xxx")(ctx) self.assertEqual(obj, Const.UNKNOWN) self.assertIsInstance(err, Exception) self.assertEqual(err.message, "left first") (obj, err) = Eq("source", "xxx")(ctx) self.assertEqual(obj, Const.UNKNOWN) self.assertIsInstance(err, KeyError) self.assertEqual(err.message, "right first") and_ = Criteria().Eq("make", "xxx").Eq("source", "yyy").And().Done() (obj, err) = and_(ctx) self.assertEqual(obj, Const.UNKNOWN) self.assertIsInstance(err, Exception) self.assertEqual(err.message, "left first") with acura: ctx = Ctx(acura, True) acura.set_compare_error("source", CompareError(KeyError("right first"))) make = ctx["make"] source = ctx["source"] and_ = And(cTrue, Eq("source", "xxx")) (obj, err) = and_(ctx) self.assertTrue(obj) self.assertIsInstance(err, KeyError) self.assertEqual(err.message, "right first") ctx = Ctx(acura, False) and_ = And(cTrue, Eq("source", "xxx")) (obj, err) = and_(ctx) self.assertEqual(obj, Const.ERROR) self.assertIsInstance(err, KeyError) self.assertEqual(err.message, "right first")
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_car_attributes(self): with acura_small as acura: self.assertEqual(acura.make, 'Acura') self.assertEqual(acura.type, 'Small') self.assertEqual(acura.maxprice, 18.8) with self.assertRaises(AttributeError): acura.not_such_attribute ctx = Ctx(acura, fuzzy=False) self.assertEqual(acura.make, ctx['make']) self.assertEqual(acura.type, ctx['type']) self.assertEqual(acura.maxprice, ctx['maxprice'], 18.8) with self.assertRaises(KeyError): ctx['not_such_attribute'] ctx = Ctx(acura, fuzzy=True) self.assertEqual(acura.make, ctx['make']) self.assertEqual(acura.type, ctx['type']) self.assertEqual(acura.maxprice, ctx['maxprice'], 18.8) with self.assertRaises(KeyError): ctx['not_such_attribute']
def test_not_eq(self): with acura_small as acura: ctx = Ctx(acura) eq_ = Eq("make", "Acura") not_ = Not(eq_) (ans, err) = eq_(ctx) self.assertTrue(ans) self.assertIsNone(err) (ans, err) = not_(ctx) self.assertFalse(ans) self.assertIsNone(err)
def test_ne_simple(self): with acura_small as acura: c = NotEq("make", "Acura") (ans, err) = c(Ctx(acura)) self.assertFalse(ans) self.assertIsNone(err) c = NotEq("make", "Mazda") (ans, err) = c(Ctx(acura)) self.assertTrue(ans) self.assertIsNone(err) c = NotEq("cpu", "Intel") (ans, err) = c(Ctx(acura)) self.assertEqual(ans, Const.ERROR) self.assertIsInstance(err, KeyError) c = NotEq("cpu", "Intel") (ans, err) = c(Ctx(acura, True)) self.assertEqual(ans, Const.UNKNOWN) self.assertIsInstance(err, KeyError)
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_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_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_fuzzy_match(self): car_search_criteria = Criteria().Between(17, "maxprice", 21).Eq("make", "Chevrolet").And().Eq("type", "Compact").And().Done() 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) with chevrolet_compact_c as chevrolet_compact: """ make maxprice missing for chevrolet_compact temporarily """ chevrolet_compact.set_access_error("maxprice", KeyError) ctx = Ctx(chevrolet_compact) (ans, err) = car_search_criteria(ctx) self.assertEqual(ans, Const.ERROR) self.assertIsInstance(err, KeyError) ctx = Ctx(chevrolet_compact, True) (ans, err) = car_search_criteria(ctx) self.assertTrue(ans) self.assertIsInstance(err, KeyError)
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)