@@ -32,6 +32,7 @@ static void test_string_methods(testing & t);
3232static void test_array_methods (testing & t);
3333static void test_object_methods (testing & t);
3434static void test_hasher (testing & t);
35+ static void test_stats (testing & t);
3536static void test_fuzzing (testing & t);
3637
3738static bool g_python_mode = false ;
@@ -70,6 +71,7 @@ int main(int argc, char *argv[]) {
7071 t.test (" object methods" , test_object_methods);
7172 if (!g_python_mode) {
7273 t.test (" hasher" , test_hasher);
74+ t.test (" stats" , test_stats);
7375 t.test (" fuzzing" , test_fuzzing);
7476 }
7577
@@ -1795,6 +1797,63 @@ static void test_hasher(testing & t) {
17951797 });
17961798}
17971799
1800+ static void test_stats (testing & t) {
1801+ static auto get_stats = [](const std::string & tmpl, const json & vars) -> jinja::value {
1802+ jinja::lexer lexer;
1803+ auto lexer_res = lexer.tokenize (tmpl);
1804+
1805+ jinja::program prog = jinja::parse_from_tokens (lexer_res);
1806+
1807+ jinja::context ctx (tmpl);
1808+ jinja::global_from_json (ctx, json{{ " val" , vars }}, true );
1809+ ctx.is_get_stats = true ;
1810+
1811+ jinja::runtime runtime (ctx);
1812+ runtime.execute (prog);
1813+
1814+ return ctx.get_val (" val" );
1815+ };
1816+
1817+ t.test (" stats" , [](testing & t) {
1818+ jinja::value val = get_stats (
1819+ " {{val.num}} "
1820+ " {{val.str}} "
1821+ " {{val.arr[0]}} "
1822+ " {{val.obj.key1}} "
1823+ " {{val.nested | tojson}}" ,
1824+ // Note: the json below will be wrapped inside "val" in the context
1825+ json{
1826+ {" num" , 1 },
1827+ {" str" , " abc" },
1828+ {" arr" , json::array ({1 , 2 , 3 })},
1829+ {" obj" , json::object ({{" key1" , 1 }, {" key2" , 2 }, {" key3" , 3 }})},
1830+ {" nested" , json::object ({
1831+ {" inner_key1" , json::array ({1 , 2 })},
1832+ {" inner_key2" , json::object ({{" a" , " x" }, {" b" , " y" }})}
1833+ })},
1834+ {" mixed" , json::object ({
1835+ {" used" , 1 },
1836+ {" unused" , 2 },
1837+ })},
1838+ }
1839+ );
1840+
1841+ t.assert_true (" num is used" , val->at (" num" )->stats .used );
1842+ t.assert_true (" str is used" , val->at (" str" )->stats .used );
1843+
1844+ t.assert_true (" arr is used" , val->at (" arr" )->stats .used );
1845+ t.assert_true (" arr[0] is used" , val->at (" arr" )->at (0 )->stats .used );
1846+ t.assert_true (" arr[1] is not used" , !val->at (" arr" )->at (1 )->stats .used );
1847+
1848+ t.assert_true (" obj is used" , val->at (" obj" )->stats .used );
1849+ t.assert_true (" obj.key1 is used" , val->at (" obj" )->at (" key1" )->stats .used );
1850+ t.assert_true (" obj.key2 is not used" , !val->at (" obj" )->at (" key2" )->stats .used );
1851+
1852+ t.assert_true (" inner_key1[0] is used" , val->at (" nested" )->at (" inner_key1" )->at (0 )->stats .used );
1853+ t.assert_true (" inner_key2.a is used" , val->at (" nested" )->at (" inner_key2" )->at (" a" )->stats .used );
1854+ });
1855+ }
1856+
17981857static void test_template_cpp (testing & t, const std::string & name, const std::string & tmpl, const json & vars, const std::string & expect) {
17991858 t.test (name, [&tmpl, &vars, &expect](testing & t) {
18001859 jinja::lexer lexer;
0 commit comments