jinja : fix quadratic cost in gather_string_parts (#27034)

* jinja : fix quadratic cost in gather_string_parts

* fix some comments

* remove test
This commit is contained in:
0
2026-08-14 23:34:40 +02:00
committed by GitHub
parent 7e4c0a9688
commit 9e40df63ba
5 changed files with 48 additions and 8 deletions
+32
View File
@@ -33,6 +33,7 @@ static void test_array_methods(testing & t);
static void test_object_methods(testing & t);
static void test_hasher(testing & t);
static void test_stats(testing & t);
static void test_string_parts(testing & t);
static void test_fuzzing(testing & t);
static bool g_python_mode = false;
@@ -72,6 +73,7 @@ int main(int argc, char *argv[]) {
if (!g_python_mode) {
t.test("hasher", test_hasher);
t.test("stats", test_stats);
t.test("string parts", test_string_parts);
t.test("fuzzing", test_fuzzing);
}
@@ -2057,6 +2059,36 @@ static void test_stats(testing & t) {
});
}
static void test_string_parts(testing & t) {
static auto render = [](const std::string & tmpl, const json & vars) -> jinja::string {
jinja::lexer lexer;
auto lexer_res = lexer.tokenize(tmpl);
jinja::program ast = jinja::parse_from_tokens(lexer_res);
jinja::context ctx(tmpl);
jinja::global_from_json(ctx, vars, true);
jinja::runtime runtime(ctx);
return runtime.gather_string_parts(runtime.execute(ast))->as_string();
};
t.test("merge joins only the neighbours with the same type", [](testing & t) {
// "AB" comes from the input and merges, "-" comes from the template and must not
jinja::string res = render("{{ val.a }}{{ val.b }}-{{ val.c }}",
json{{"val", json{{"a", "A"}, {"b", "B"}, {"c", "C"}}}});
if (t.assert_true("3 parts after the merge", res.parts.size() == 3)) {
t.assert_true("part 0 is the merged input", res.parts[0].val == "AB" && res.parts[0].is_input);
t.assert_true("part 1 is from the template", res.parts[1].val == "-" && !res.parts[1].is_input);
t.assert_true("part 2 is input", res.parts[2].val == "C" && res.parts[2].is_input);
} else {
t.log("parts: " + std::to_string(res.parts.size()) + ", rendered: " + json(res.str()).dump());
}
});
}
static void test_template_cpp(testing & t, const std::string & name, const std::string & tmpl, const json & vars, const std::string & expect) {
t.test(name, [&tmpl, &vars, &expect](testing & t) {
jinja::lexer lexer;