diff --git a/HISTORY.md b/HISTORY.md index 072ddac0..bb49b1c6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,6 +4,7 @@ **Features** +- support new variable notation ${var} - use \$\$ to escape \$ notation **Bugfixes** diff --git a/httprunner/parser.py b/httprunner/parser.py index e74919ac..f80af2d0 100644 --- a/httprunner/parser.py +++ b/httprunner/parser.py @@ -9,10 +9,9 @@ from httprunner.compat import basestring, builtin_str, numeric_types, str # use $$ to escape $ notation dolloar_regex_compile = re.compile(r"\$\$") -# TODO: change variable notation from $var to {{var}} -# $var_1 -variable_regex_compile = re.compile(r"\$(\w+)") -# ${func1($var_1, $var_3)} +# variable notation, e.g. ${var} or $var +variable_regex_compile = re.compile(r"\$\{(\w+)\}|\$(\w+)") +# function notation, e.g. ${func1($var_1, $var_3)} function_regex_compile = re.compile(r"\$\{(\w+)\(([\$\w\.\-/\s=,]*)\)\}") @@ -70,7 +69,12 @@ def regex_findall_variables(content): """ try: - return variable_regex_compile.findall(content) + vars_list = [] + for var_tuple in variable_regex_compile.findall(content): + vars_list.append( + var_tuple[0] or var_tuple[1] + ) + return vars_list except TypeError: return [] @@ -477,10 +481,10 @@ class LazyString(object): self._string += "{}" continue - # search variable like $var + # search variable like ${var} or $var var_match = variable_regex_compile.match(raw_string, match_start_position) if var_match: - var_name = var_match.group(1) + var_name = var_match.group(1) or var_match.group(2) # check if any variable undefined in check_variables_set if var_name not in self.check_variables_set: raise exceptions.VariableNotFound(var_name) diff --git a/tests/test_parser.py b/tests/test_parser.py index 3c2a0455..57945547 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -37,6 +37,10 @@ class TestParserBasic(unittest.TestCase): parser.regex_findall_variables("a$var"), ["var"] ) + self.assertEqual( + parser.regex_findall_variables("a$var${var2}$var3${var4}"), + ["var", "var2", "var3", "var4"] + ) self.assertEqual( parser.regex_findall_variables("$v ar"), ["v"] @@ -281,7 +285,7 @@ class TestParserBasic(unittest.TestCase): {"abc": "def"} ) - def test_lazy_string(self): + def test_parse_func_var_abnormal(self): variables_mapping = { "var_1": "abc", "var_2": "def", @@ -295,6 +299,150 @@ class TestParserBasic(unittest.TestCase): "func1": lambda x,y: str(x) + str(y) } + # { + var = parser.LazyString("ABC$var_1{", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}{{") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc{") + + # } + var = parser.LazyString("ABC$var_1}", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}}}") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc}") + + # $$ + var = parser.LazyString("ABC$$var_1{", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC$var_1{{") + self.assertEqual(var._args, []) + self.assertEqual(var.to_value(variables_mapping), "ABC$var_1{") + + # $$$ + var = parser.LazyString("ABC$$$var_1{", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC${}{{") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABC$abc{") + + # $$$$ + var = parser.LazyString("ABC$$$$var_1{", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC$$var_1{{") + self.assertEqual(var._args, []) + self.assertEqual(var.to_value(variables_mapping), "ABC$$var_1{") + + # ${ + var = parser.LazyString("ABC$var_1${", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}${{") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc${") + + var = parser.LazyString("ABC$var_1${a", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}${{a") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc${a") + + # $} + var = parser.LazyString("ABC$var_1$}a", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}$}}a") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc$}a") + + # }{ + var = parser.LazyString("ABC$var_1}{a", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}}}{{a") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc}{a") + + # {} + var = parser.LazyString("ABC$var_1{}a", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}{{}}a") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc{}a") + + def test_parse_func_var_duplicate(self): + variables_mapping = { + "var_1": "abc", + "var_2": "def", + "var_3": 123, + "var_4": {"a": 1}, + "var_5": True, + "var_6": None + } + check_variables_set = variables_mapping.keys() + functions_mapping = { + "func1": lambda x,y: str(x) + str(y) + } + var = parser.LazyString( + "ABC${func1($var_1, $var_3)}--${func1($var_1, $var_3)}", + functions_mapping, + check_variables_set + ) + self.assertEqual(var._string, "ABC{}--{}") + self.assertEqual(var.to_value(variables_mapping), "ABCabc123--abc123") + + var = parser.LazyString("ABC${func1($var_1, $var_3)}$var_1", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}{}") + self.assertEqual(var.to_value(variables_mapping), "ABCabc123abc") + + var = parser.LazyString( + "ABC${func1($var_1, $var_3)}$var_1--${func1($var_1, $var_3)}$var_1", + functions_mapping, + check_variables_set + ) + self.assertEqual(var._string, "ABC{}{}--{}{}") + self.assertEqual(var.to_value(variables_mapping), "ABCabc123abc--abc123abc") + + def test_parse_function(self): + variables_mapping = { + "var_1": "abc", + "var_2": "def", + "var_3": 123, + "var_4": {"a": 1}, + "var_5": True, + "var_6": None + } + check_variables_set = variables_mapping.keys() + functions_mapping = { + "func1": lambda x,y: str(x) + str(y) + } + + var = parser.LazyString("${func1($var_1, $var_3)}", functions_mapping, check_variables_set) + self.assertEqual(var._string, "{}") + self.assertIsInstance(var._args[0], parser.LazyFunction) + self.assertEqual(var.to_value(variables_mapping), "abc123") + + var = parser.LazyString("ABC${func1($var_1, $var_3)}DE", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}DE") + self.assertIsInstance(var._args[0], parser.LazyFunction) + self.assertEqual(var.to_value(variables_mapping), "ABCabc123DE") + + var = parser.LazyString("ABC${func1($var_1, $var_3)}$var_5", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}{}") + self.assertEqual(var.to_value(variables_mapping), "ABCabc123True") + + var = parser.LazyString("ABC${func1($var_1, $var_3)}DE$var_4", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}DE{}") + self.assertEqual(var.to_value(variables_mapping), "ABCabc123DE{'a': 1}") + + var = parser.LazyString("ABC$var_5${func1($var_1, $var_3)}", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}{}") + self.assertEqual(var.to_value(variables_mapping), "ABCTrueabc123") + + + def test_parse_variable(self): + """ variable format ${var} and $var + """ + variables_mapping = { + "var_1": "abc", + "var_2": "def", + "var_3": 123, + "var_4": {"a": 1}, + "var_5": True, + "var_6": None + } + check_variables_set = variables_mapping.keys() + functions_mapping = {} + + # format: $var var = parser.LazyString("ABC$var_1", functions_mapping, check_variables_set) self.assertEqual(var._string, "ABC{}") self.assertEqual(var._args, ["var_1"]) @@ -325,56 +473,6 @@ class TestParserBasic(unittest.TestCase): self.assertEqual(var._args, ["var_1", "var_1"]) self.assertEqual(var.to_value(variables_mapping), "ABCabc/123abc/456") - var = parser.LazyString("ABC$var_1{", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}{{") - self.assertEqual(var._args, ["var_1"]) - self.assertEqual(var.to_value(variables_mapping), "ABCabc{") - - var = parser.LazyString("ABC$var_1}", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}}}") - self.assertEqual(var._args, ["var_1"]) - self.assertEqual(var.to_value(variables_mapping), "ABCabc}") - - var = parser.LazyString("ABC$$var_1{", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC$var_1{{") - self.assertEqual(var._args, []) - self.assertEqual(var.to_value(variables_mapping), "ABC$var_1{") - - var = parser.LazyString("ABC$$$var_1{", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC${}{{") - self.assertEqual(var._args, ["var_1"]) - self.assertEqual(var.to_value(variables_mapping), "ABC$abc{") - - var = parser.LazyString("ABC$$$$var_1{", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC$$var_1{{") - self.assertEqual(var._args, []) - self.assertEqual(var.to_value(variables_mapping), "ABC$$var_1{") - - var = parser.LazyString("ABC$var_1${", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}${{") - self.assertEqual(var._args, ["var_1"]) - self.assertEqual(var.to_value(variables_mapping), "ABCabc${") - - var = parser.LazyString("ABC$var_1${a", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}${{a") - self.assertEqual(var._args, ["var_1"]) - self.assertEqual(var.to_value(variables_mapping), "ABCabc${a") - - var = parser.LazyString("ABC$var_1$}a", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}$}}a") - self.assertEqual(var._args, ["var_1"]) - self.assertEqual(var.to_value(variables_mapping), "ABCabc$}a") - - var = parser.LazyString("ABC$var_1}{a", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}}}{{a") - self.assertEqual(var._args, ["var_1"]) - self.assertEqual(var.to_value(variables_mapping), "ABCabc}{a") - - var = parser.LazyString("ABC$var_1{}a", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}{{}}a") - self.assertEqual(var._args, ["var_1"]) - self.assertEqual(var.to_value(variables_mapping), "ABCabc{}a") - var = parser.LazyString("ABC$var_1/$var_2/$var_1", functions_mapping, check_variables_set) self.assertEqual(var._string, "ABC{}/{}/{}") self.assertEqual(var._args, ["var_1", "var_2", "var_1"]) @@ -385,47 +483,46 @@ class TestParserBasic(unittest.TestCase): self.assertEqual(var._args, ["var_1", "var_3"]) self.assertEqual(var.to_value(variables_mapping), "func1(abc, 123)") - var = parser.LazyString("${func1($var_1, $var_3)}", functions_mapping, check_variables_set) - self.assertEqual(var._string, "{}") - self.assertIsInstance(var._args[0], parser.LazyFunction) - self.assertEqual(var.to_value(variables_mapping), "abc123") + # format: ${var} + var = parser.LazyString("ABC${var_1}", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc") - var = parser.LazyString("ABC${func1($var_1, $var_3)}DE", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}DE") - self.assertIsInstance(var._args[0], parser.LazyFunction) - self.assertEqual(var.to_value(variables_mapping), "ABCabc123DE") - - var = parser.LazyString("ABC${func1($var_1, $var_3)}$var_5", functions_mapping, check_variables_set) + var = parser.LazyString("ABC${var_1}${var_3}", functions_mapping, check_variables_set) self.assertEqual(var._string, "ABC{}{}") - self.assertEqual(var.to_value(variables_mapping), "ABCabc123True") + self.assertEqual(var._args, ["var_1", "var_3"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc123") - var = parser.LazyString( - "ABC${func1($var_1, $var_3)}--${func1($var_1, $var_3)}", - functions_mapping, - check_variables_set - ) - self.assertEqual(var._string, "ABC{}--{}") - self.assertEqual(var.to_value(variables_mapping), "ABCabc123--abc123") + var = parser.LazyString("ABC${var_1}/${var_3}", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}/{}") + self.assertEqual(var._args, ["var_1", "var_3"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc/123") - var = parser.LazyString("ABC${func1($var_1, $var_3)}$var_1", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}{}") - self.assertEqual(var.to_value(variables_mapping), "ABCabc123abc") + var = parser.LazyString("ABC${var_1}/", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}/") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc/") - var = parser.LazyString( - "ABC${func1($var_1, $var_3)}$var_1--${func1($var_1, $var_3)}$var_1", - functions_mapping, - check_variables_set - ) - self.assertEqual(var._string, "ABC{}{}--{}{}") - self.assertEqual(var.to_value(variables_mapping), "ABCabc123abc--abc123abc") + var = parser.LazyString("ABC${var_1}123", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}123") + self.assertEqual(var._args, ["var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc123") - var = parser.LazyString("ABC${func1($var_1, $var_3)}DE$var_4", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}DE{}") - self.assertEqual(var.to_value(variables_mapping), "ABCabc123DE{'a': 1}") + var = parser.LazyString("ABC${var_1}/123${var_1}/456", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}/123{}/456") + self.assertEqual(var._args, ["var_1", "var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc/123abc/456") - var = parser.LazyString("ABC$var_5${func1($var_1, $var_3)}", functions_mapping, check_variables_set) - self.assertEqual(var._string, "ABC{}{}") - self.assertEqual(var.to_value(variables_mapping), "ABCTrueabc123") + var = parser.LazyString("ABC${var_1}/${var_2}/${var_1}", functions_mapping, check_variables_set) + self.assertEqual(var._string, "ABC{}/{}/{}") + self.assertEqual(var._args, ["var_1", "var_2", "var_1"]) + self.assertEqual(var.to_value(variables_mapping), "ABCabc/def/abc") + + var = parser.LazyString("func1(${var_1}, ${var_3})", functions_mapping, check_variables_set) + self.assertEqual(var._string, "func1({}, {})") + self.assertEqual(var._args, ["var_1", "var_3"]) + self.assertEqual(var.to_value(variables_mapping), "func1(abc, 123)") def test_parse_data_multiple_identical_variables(self): variables_mapping = {