From 8e4a9bad8a75253f977bd0a308d62507d7d9fac7 Mon Sep 17 00:00:00 2001 From: ochafik Date: Thu, 26 Sep 2024 05:53:12 +0100 Subject: [PATCH] `minja`: allow none input to selectattr, and add safe passthrough filter --- common/minja.hpp | 5 +++++ tests/test-minja.cpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/common/minja.hpp b/common/minja.hpp index 661f9c3c7..fef6d5fef 100644 --- a/common/minja.hpp +++ b/common/minja.hpp @@ -2329,6 +2329,9 @@ inline std::shared_ptr Context::builtins() { auto & items = args.at("items"); return (int64_t) items.size(); })); + globals.set("safe", simple_function("safe", { "value" }, [](const std::shared_ptr &, Value & args) -> Value { + return args.at("value"); + })); globals.set("list", simple_function("list", { "items" }, [](const std::shared_ptr &, Value & args) -> Value { auto & items = args.at("items"); if (!items.is_array()) throw std::runtime_error("object is not iterable"); @@ -2415,6 +2418,8 @@ inline std::shared_ptr Context::builtins() { globals.set("selectattr", Value::callable([=](const std::shared_ptr & context, Value::Arguments & args) { args.expectArgs("selectattr", {2, std::numeric_limits::max()}, {0, 0}); auto & items = args.args[0]; + if (items.is_null()) + return Value::array(); auto attr_name = args.args[1].get(); bool has_test = false; diff --git a/tests/test-minja.cpp b/tests/test-minja.cpp index 1cbf2c994..8b702cbb0 100644 --- a/tests/test-minja.cpp +++ b/tests/test-minja.cpp @@ -149,7 +149,9 @@ static void test_error_contains(const std::string & template_str, const json & b } static void test_template_features() { + test_render(R"({{ 1 | safe }})", {}, {}, "1"); test_render(R"({{ 'abc'.endswith('bc') }},{{ ''.endswith('a') }})", {}, {}, "True,False"); + test_render(R"({{ none | selectattr("foo", "equalto", "bar") | list }})", {}, {}, "[]"); test_render(R"({{ 'a' in {"a": 1} }},{{ 'a' in {} }})", {}, {}, "True,False"); test_render(R"({{ 'a' in ["a"] }},{{ 'a' in [] }})", {}, {}, "True,False"); test_render(R"({{ [{"a": 1}, {"a": 2}, {}] | selectattr("a", "equalto", 1) }})", {}, {}, R"([{'a': 1}])");