drun 2.3.2__tar.gz → 2.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {drun-2.3.2 → drun-2.3.4}/PKG-INFO +1 -1
- {drun-2.3.2 → drun-2.3.4}/drun/__init__.py +1 -1
- {drun-2.3.2 → drun-2.3.4}/drun/templating/engine.py +14 -15
- {drun-2.3.2 → drun-2.3.4}/drun.egg-info/PKG-INFO +1 -1
- {drun-2.3.2 → drun-2.3.4}/drun.egg-info/SOURCES.txt +2 -1
- {drun-2.3.2 → drun-2.3.4}/pyproject.toml +1 -1
- drun-2.3.4/tests/test_templating.py +40 -0
- {drun-2.3.2 → drun-2.3.4}/LICENSE +0 -0
- {drun-2.3.2 → drun-2.3.4}/README.md +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/cli.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/db/__init__.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/db/database_proxy.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/db/generate_mysql_config.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/engine/__init__.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/engine/http.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/exporters/curl.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/importers/base.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/importers/curl.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/importers/har.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/importers/openapi.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/importers/postman.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/loader/__init__.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/loader/collector.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/loader/env.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/loader/hooks.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/loader/yaml_loader.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/models/case.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/models/config.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/models/report.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/models/request.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/models/step.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/models/validators.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/notifier/__init__.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/notifier/base.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/notifier/dingtalk.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/notifier/emailer.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/notifier/feishu.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/notifier/format.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/reporter/__init__.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/reporter/allure_reporter.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/reporter/html_reporter.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/reporter/json_reporter.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/runner/__init__.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/runner/assertions.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/runner/extractors.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/runner/runner.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/scaffolds/__init__.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/scaffolds/templates.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/templating/__init__.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/templating/builtins.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/templating/context.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/utils/__init__.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/utils/curl.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/utils/errors.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/utils/logging.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/utils/mask.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun/utils/timeit.py +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun.egg-info/dependency_links.txt +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun.egg-info/entry_points.txt +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun.egg-info/requires.txt +0 -0
- {drun-2.3.2 → drun-2.3.4}/drun.egg-info/top_level.txt +0 -0
- {drun-2.3.2 → drun-2.3.4}/setup.cfg +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "2.3.
|
|
2
|
+
__version__ = "2.3.3"
|
|
@@ -142,25 +142,24 @@ class TemplateEngine:
|
|
|
142
142
|
dyn_funcs: Dict[str, Callable[..., Any]] = {"ENV": ENV}
|
|
143
143
|
ctx: Dict[str, Any] = {**BUILTINS, **dyn_funcs, **(functions or {}), **variables}
|
|
144
144
|
|
|
145
|
-
# If the whole string is a single ${...} token, evaluate and return the value with its native type
|
|
146
|
-
single_token_match = re.fullmatch(r"\$\{([^{}]+)\}", text)
|
|
147
|
-
if single_token_match:
|
|
148
|
-
expr = single_token_match.group(1).strip()
|
|
149
|
-
try:
|
|
150
|
-
node = ast.parse(expr, mode="eval")
|
|
151
|
-
return _safe_eval(node, ctx)
|
|
152
|
-
except Exception:
|
|
153
|
-
# Fall through to string rendering if evaluation fails
|
|
154
|
-
pass
|
|
155
|
-
|
|
156
|
-
# multi-pass to resolve nested tokens inside strings, always producing a string
|
|
157
145
|
cur = text
|
|
158
|
-
for _ in range(
|
|
146
|
+
for _ in range(5):
|
|
147
|
+
single_token_match = re.fullmatch(r"\$\{([^{}]+)\}", cur)
|
|
148
|
+
if single_token_match:
|
|
149
|
+
expr = single_token_match.group(1).strip()
|
|
150
|
+
try:
|
|
151
|
+
node = ast.parse(expr, mode="eval")
|
|
152
|
+
return _safe_eval(node, ctx)
|
|
153
|
+
except Exception:
|
|
154
|
+
# Fall through and continue resolving nested tokens if evaluation fails
|
|
155
|
+
pass
|
|
159
156
|
nxt = _render_text_without_jinja(cur, ctx)
|
|
160
|
-
if nxt == cur
|
|
161
|
-
cur = nxt
|
|
157
|
+
if nxt == cur:
|
|
162
158
|
break
|
|
163
159
|
cur = nxt
|
|
160
|
+
if "${" not in cur:
|
|
161
|
+
break
|
|
162
|
+
# If we weren't able to evaluate to a native type, return the rendered string
|
|
164
163
|
return cur
|
|
165
164
|
except Exception:
|
|
166
165
|
return value
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import unittest
|
|
4
|
+
|
|
5
|
+
from drun.templating.engine import TemplateEngine
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TemplateEngineHookTests(unittest.TestCase):
|
|
9
|
+
def setUp(self) -> None:
|
|
10
|
+
self.templater = TemplateEngine()
|
|
11
|
+
|
|
12
|
+
def test_nested_hook_calls_preserve_native_types(self) -> None:
|
|
13
|
+
funcs = {
|
|
14
|
+
"double": lambda x: x * 2,
|
|
15
|
+
"increment": lambda val: int(val) + 1,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
base_vars = self.templater.render_value({"start": "${double(2)}"}, {}, funcs)
|
|
19
|
+
self.assertEqual(base_vars["start"], 4)
|
|
20
|
+
self.assertIsInstance(base_vars["start"], int)
|
|
21
|
+
|
|
22
|
+
step_vars = self.templater.render_value(
|
|
23
|
+
{"payload": "${double($start)}"},
|
|
24
|
+
{**base_vars},
|
|
25
|
+
funcs,
|
|
26
|
+
)
|
|
27
|
+
self.assertEqual(step_vars["payload"], 8)
|
|
28
|
+
self.assertIsInstance(step_vars["payload"], int)
|
|
29
|
+
|
|
30
|
+
expect_value = self.templater.render_value(
|
|
31
|
+
"${increment($payload)}",
|
|
32
|
+
{**base_vars, **step_vars},
|
|
33
|
+
funcs,
|
|
34
|
+
)
|
|
35
|
+
self.assertEqual(expect_value, 9)
|
|
36
|
+
self.assertIsInstance(expect_value, int)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|