""" 条件评估器单元测试 测试 ConditionEvaluator 类的所有功能 """ import pytest from loaders.yaml_loader import YAMLError from core.condition_evaluator import ConditionEvaluator class TestConditionEvaluator: """ConditionEvaluator 测试类""" def setup_method(self): """每个测试方法前执行""" self.evaluator = ConditionEvaluator() # ============= 比较运算符测试 ============= def test_greater_than(self): """测试大于运算符""" assert self.evaluator.evaluate_condition("{count > 0}", {"count": 5}) is True assert self.evaluator.evaluate_condition("{count > 0}", {"count": 0}) is False def test_less_than(self): """测试小于运算符""" assert self.evaluator.evaluate_condition("{count < 10}", {"count": 5}) is True assert self.evaluator.evaluate_condition("{count < 10}", {"count": 10}) is False def test_greater_equal(self): """测试大于等于运算符""" assert self.evaluator.evaluate_condition("{count >= 5}", {"count": 5}) is True assert self.evaluator.evaluate_condition("{count >= 5}", {"count": 4}) is False def test_less_equal(self): """测试小于等于运算符""" assert self.evaluator.evaluate_condition("{count <= 5}", {"count": 5}) is True assert self.evaluator.evaluate_condition("{count <= 5}", {"count": 6}) is False def test_equal(self): """测试相等运算符""" assert self.evaluator.evaluate_condition("{status == 'active'}", {"status": "active"}) is True assert self.evaluator.evaluate_condition("{status == 'active'}", {"status": "inactive"}) is False def test_not_equal(self): """测试不等运算符""" assert self.evaluator.evaluate_condition("{status != 'inactive'}", {"status": "active"}) is True assert self.evaluator.evaluate_condition("{status != 'active'}", {"status": "active"}) is False # ============= 逻辑运算符测试 ============= def test_logical_and(self): """测试逻辑与运算""" assert self.evaluator.evaluate_condition( "{count > 0 and status == 'active'}", {"count": 5, "status": "active"} ) is True assert self.evaluator.evaluate_condition( "{count > 0 and status == 'active'}", {"count": 0, "status": "active"} ) is False def test_logical_or(self): """测试逻辑或运算""" assert self.evaluator.evaluate_condition( "{count > 0 or status == 'active'}", {"count": 0, "status": "active"} ) is True assert self.evaluator.evaluate_condition( "{count > 0 or status == 'active'}", {"count": 0, "status": "inactive"} ) is False def test_logical_not(self): """测试逻辑非运算""" assert self.evaluator.evaluate_condition("{not (count == 0)}", {"count": 5}) is True assert self.evaluator.evaluate_condition("{not (count == 0)}", {"count": 0}) is False # ============= 成员测试 ============= def test_in_list(self): """测试列表成员测试""" assert self.evaluator.evaluate_condition( "{status in ['draft', 'review', 'published']}", {"status": "draft"} ) is True assert self.evaluator.evaluate_condition( "{status in ['draft', 'review']}", {"status": "active"} ) is False def test_not_in_list(self): """测试列表非成员测试""" assert self.evaluator.evaluate_condition( "{status not in ['draft', 'review']}", {"status": "active"} ) is True assert self.evaluator.evaluate_condition( "{status not in ['draft', 'review']}", {"status": "draft"} ) is False def test_in_tuple(self): """测试元组成员测试""" assert self.evaluator.evaluate_condition( "{level in (1, 2, 3)}", {"level": 2} ) is True assert self.evaluator.evaluate_condition( "{level in (1, 2, 3)}", {"level": 4} ) is False def test_string_contains(self): """测试字符串包含""" assert self.evaluator.evaluate_condition( "{'test' in status}", {"status": "test-version"} ) is True assert self.evaluator.evaluate_condition( "{'test' in status}", {"status": "production"} ) is False # ============= 数学运算测试 ============= def test_addition(self): """测试加法运算""" assert self.evaluator.evaluate_condition( "{(price + tax) > 100}", {"price": 90, "tax": 15} ) is True def test_multiplication(self): """测试乘法运算""" assert self.evaluator.evaluate_condition( "{(price * discount) > 50}", {"price": 100, "discount": 0.8} ) is True def test_division(self): """测试除法运算""" assert self.evaluator.evaluate_condition( "{(total / count) >= 10}", {"total": 100, "count": 5} ) is True def test_modulo(self): """测试取模运算""" assert self.evaluator.evaluate_condition( "{(value % 2) == 0}", {"value": 10} ) is True def test_power(self): """测试幂运算""" assert self.evaluator.evaluate_condition( "{(base ** exp) > 100}", {"base": 10, "exp": 2} ) is False # ============= 内置函数测试 ============= def test_int_function(self): """测试 int() 函数""" assert self.evaluator.evaluate_condition( "{int(value) > 100}", {"value": "150"} ) is True def test_float_function(self): """测试 float() 函数""" assert self.evaluator.evaluate_condition( "{float(value) > 3.14}", {"value": "3.5"} ) is True def test_str_function(self): """测试 str() 函数""" assert self.evaluator.evaluate_condition( "{str(value) == '123'}", {"value": 123} ) is True def test_len_function(self): """测试 len() 函数""" assert self.evaluator.evaluate_condition( "{len(items) > 0}", {"items": [1, 2, 3]} ) is True def test_bool_function(self): """测试 bool() 函数""" assert self.evaluator.evaluate_condition( "{bool(value)}", {"value": "text"} ) is True assert self.evaluator.evaluate_condition( "{bool(value)}", {"value": ""} ) is False def test_abs_function(self): """测试 abs() 函数""" assert self.evaluator.evaluate_condition( "{abs(value) > 10}", {"value": -15} ) is True def test_min_function(self): """测试 min() 函数""" assert self.evaluator.evaluate_condition( "{min(a, b) == 5}", {"a": 5, "b": 10} ) is True def test_max_function(self): """测试 max() 函数""" assert self.evaluator.evaluate_condition( "{max(a, b) == 10}", {"a": 5, "b": 10} ) is True # ============= 复杂逻辑组合测试 ============= def test_complex_logic_combination(self): """测试复杂逻辑组合""" assert self.evaluator.evaluate_condition( "{(score >= 60 and score <= 100) or is_admin}", {"score": 75, "is_admin": False} ) is True def test_nested_conditions(self): """测试嵌套条件""" assert self.evaluator.evaluate_condition( "{((count > 0) and (status == 'active')) or (is_admin and (level >= 3))}", {"count": 5, "status": "active", "is_admin": False, "level": 1} ) is True # ============= 错误处理测试 ============= def test_undefined_variable_error(self): """测试变量未定义错误""" with pytest.raises(YAMLError, match="条件表达式中的变量未定义"): self.evaluator.evaluate_condition("{undefined_var > 0}", {"count": 5}) def test_undefined_function_error(self): """测试函数未定义错误""" with pytest.raises(YAMLError, match="条件表达式中使用了不支持的函数"): self.evaluator.evaluate_condition("{custom_func(value)}", {"value": 5}) def test_syntax_error(self): """测试语法错误""" with pytest.raises(YAMLError, match="条件表达式语法错误"): self.evaluator.evaluate_condition("{count > }", {"count": 5}) # ============= 安全限制测试 ============= def test_expression_too_long(self): """测试表达式过长""" long_expr = "{" + "x " * 300 + "}" with pytest.raises(YAMLError, match="条件表达式过长"): self.evaluator.evaluate_condition(long_expr, {"x": 1}) def test_attribute_access_forbidden(self): """测试禁止属性访问""" with pytest.raises(YAMLError, match="条件表达式使用了不支持的语法特性"): self.evaluator.evaluate_condition("{obj.attr}", {"obj": object()}) # ============= 表达式提取测试 ============= def test_extract_expression_with_braces(self): """测试提取带花括号的表达式""" expr = self.evaluator._extract_expression("{count > 0}") assert expr == "count > 0" def test_extract_expression_with_whitespace(self): """测试提取带空白的表达式""" expr = self.evaluator._extract_expression("{ count > 0 }") assert expr == "count > 0" def test_extract_expression_without_braces(self): """测试提取不带花括号的表达式""" expr = self.evaluator._extract_expression("count > 0") assert expr == "count > 0" # ============= 向后兼容测试 ============= def test_backward_compatible_simple_expression(self): """测试向后兼容的简单表达式""" assert self.evaluator.evaluate_condition( "{subtitle != ''}", {"subtitle": "Hello"} ) is True assert self.evaluator.evaluate_condition( "{subtitle != ''}", {"subtitle": ""} ) is False