diff --git a/common/jinja/runtime.cpp b/common/jinja/runtime.cpp index af2282c546..dce5bbae30 100644 --- a/common/jinja/runtime.cpp +++ b/common/jinja/runtime.cpp @@ -667,8 +667,9 @@ value macro_statement::execute_impl(context & ctx) { if (is_stmt(this->args[i])) { // normal parameter std::string param_name = cast_stmt(this->args[i])->val; - JJ_DEBUG(" Binding parameter '%s' to argument of type %s", param_name.c_str(), args.get_pos(i)->type().c_str()); - macro_ctx.set_val(param_name, args.get_pos(i)); + value param_value = args.get_kwarg_or_pos(param_name, i); + JJ_DEBUG(" Binding parameter '%s' to argument of type %s", param_name.c_str(), param_value->type().c_str()); + macro_ctx.set_val(param_name, param_value); } else if (is_stmt(this->args[i])) { // default argument used as normal parameter auto kwarg = cast_stmt(this->args[i]); @@ -676,8 +677,9 @@ value macro_statement::execute_impl(context & ctx) { throw std::runtime_error("Keyword argument key must be an identifier in macro '" + name + "'"); } std::string param_name = cast_stmt(kwarg->key)->val; - JJ_DEBUG(" Binding parameter '%s' to argument of type %s", param_name.c_str(), args.get_pos(i)->type().c_str()); - macro_ctx.set_val(param_name, args.get_pos(i)); + value param_value = args.get_kwarg_or_pos(param_name, i); + JJ_DEBUG(" Binding parameter '%s' to argument of type %s", param_name.c_str(), param_value->type().c_str()); + macro_ctx.set_val(param_name, param_value); } else { throw std::runtime_error("Invalid parameter type in macro '" + name + "'"); } diff --git a/tests/test-jinja.cpp b/tests/test-jinja.cpp index 1550627bf0..2cac38f02a 100644 --- a/tests/test-jinja.cpp +++ b/tests/test-jinja.cpp @@ -884,6 +884,24 @@ static void test_macros(testing & t) { json::object(), "Hi Guest" ); + + test_template(t, "macro kwargs input", + "{% macro my_func(a, b=False) %}{% if b %}{{ a }}{% else %}nope{% endif %}{% endmacro %}{{ my_func(1, b=True) }}", + json::object(), + "1" + ); + + test_template(t, "macro with multiple args", + "{% macro add(a, b, c=0) %}{{ a + b + c }}{% endmacro %}{{ add(1, 2) }},{{ add(1, 2, 3) }},{{ add(1, b=10) }},{{ add(1, 2, c=5) }}", + json::object(), + "3,6,11,8" + ); + + test_template(t, "macro with kwarg out-of-order input", + "{% macro greet(first, last, greeting='Hello') %}{{ greeting }}, {{ first }} {{ last }}{% endmacro %}{{ greet(last='Smith', first='John') }},{{ greet(last='Doe', greeting='Hi', first='Jane') }}", + json::object(), + "Hello, John Smith,Hi, Jane Doe" + ); } static void test_namespace(testing & t) {